@charterlabs/rhinestone-sdk 0.1.12 → 0.2.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 +181 -74
- package/dist/src/accounts/index.d.ts +8 -7
- package/dist/src/accounts/index.d.ts.map +1 -1
- package/dist/src/accounts/index.js +65 -172
- package/dist/src/accounts/index.test.js +2 -3
- package/dist/src/accounts/kernel.d.ts +3 -2
- package/dist/src/accounts/kernel.d.ts.map +1 -1
- package/dist/src/accounts/kernel.js +3 -5
- package/dist/src/accounts/kernel.test.js +5 -12
- package/dist/src/accounts/nexus.d.ts +2 -2
- package/dist/src/accounts/nexus.d.ts.map +1 -1
- package/dist/src/accounts/nexus.js +17 -17
- package/dist/src/accounts/nexus.test.js +11 -14
- package/dist/src/accounts/safe.d.ts +2 -2
- package/dist/src/accounts/safe.d.ts.map +1 -1
- package/dist/src/accounts/safe.js +3 -5
- package/dist/src/accounts/safe.test.js +4 -7
- package/dist/src/accounts/signing/common.d.ts +23 -0
- package/dist/src/accounts/signing/common.d.ts.map +1 -0
- package/dist/src/accounts/signing/common.js +113 -0
- package/dist/src/accounts/signing/message.d.ts +5 -0
- package/dist/src/accounts/signing/message.d.ts.map +1 -0
- package/dist/src/accounts/signing/message.js +51 -0
- package/dist/src/accounts/signing/typedData.d.ts +5 -0
- package/dist/src/accounts/signing/typedData.d.ts.map +1 -0
- package/dist/src/accounts/signing/typedData.js +39 -0
- package/dist/src/accounts/startale.d.ts +2 -2
- package/dist/src/accounts/startale.d.ts.map +1 -1
- package/dist/src/accounts/startale.js +3 -3
- package/dist/src/accounts/startale.test.js +4 -7
- package/dist/src/actions/index.d.ts +84 -0
- package/dist/src/actions/index.d.ts.map +1 -1
- package/dist/src/actions/index.js +92 -0
- package/dist/src/actions/index.test.js +15 -15
- package/dist/src/actions/smart-session.d.ts +6 -0
- package/dist/src/actions/smart-session.d.ts.map +1 -1
- package/dist/src/actions/smart-session.js +6 -0
- package/dist/src/execution/compact.d.ts +128 -1
- package/dist/src/execution/compact.d.ts.map +1 -1
- package/dist/src/execution/compact.js +91 -0
- package/dist/src/execution/index.d.ts.map +1 -1
- package/dist/src/execution/index.js +2 -3
- package/dist/src/execution/utils.d.ts +6 -5
- package/dist/src/execution/utils.d.ts.map +1 -1
- package/dist/src/execution/utils.js +37 -17
- package/dist/src/index.d.ts +8 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +89 -31
- package/dist/src/modules/index.d.ts +3 -8
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js +26 -27
- package/dist/src/modules/index.test.js +1 -4
- package/dist/src/modules/validators/core.d.ts.map +1 -1
- package/dist/src/modules/validators/core.js +19 -14
- package/dist/src/modules/validators/core.test.js +4 -11
- package/dist/src/modules/validators/index.d.ts +1 -2
- package/dist/src/modules/validators/index.d.ts.map +1 -1
- package/dist/src/modules/validators/index.js +1 -13
- package/dist/src/modules/validators/smart-sessions.js +3 -3
- package/dist/src/modules/validators/smart-sessions.test.js +4 -4
- package/dist/src/orchestrator/index.d.ts +1 -2
- package/dist/src/orchestrator/index.d.ts.map +1 -1
- package/dist/src/orchestrator/index.js +1 -3
- package/dist/src/orchestrator/utils.d.ts +1 -3
- package/dist/src/orchestrator/utils.d.ts.map +1 -1
- package/dist/src/orchestrator/utils.js +0 -102
- package/dist/src/types.d.ts +2 -5
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,107 +1,214 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Rhinestone SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
End-to-end chain abstraction and modularity toolkit
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Usage
|
|
6
6
|
|
|
7
|
-
###
|
|
8
|
-
- **Multi-credential support** - Register multiple WebAuthn devices per account
|
|
9
|
-
- **Threshold signatures** - M-of-N security model for enterprise use
|
|
10
|
-
- **User verification control** - Configurable UV requirements per credential
|
|
11
|
-
- **WebAuthn standard compliance** - Proper credential ID handling
|
|
12
|
-
- **Production-ready** - Handles real-world multi-device scenarios
|
|
7
|
+
### Installation
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- ✅ **Security flexibility** vs fixed UV policies
|
|
18
|
-
- ✅ **Enterprise features** vs demo/MVP approach
|
|
9
|
+
```bash
|
|
10
|
+
npm install viem @rhinestone/sdk
|
|
11
|
+
```
|
|
19
12
|
|
|
20
|
-
|
|
13
|
+
```bash
|
|
14
|
+
pnpm install viem @rhinestone/sdk
|
|
15
|
+
```
|
|
21
16
|
|
|
22
17
|
```bash
|
|
23
|
-
|
|
24
|
-
# or
|
|
25
|
-
bun add @charterlabs/rhinestone-sdk viem
|
|
18
|
+
yarn add viem @rhinestone/sdk
|
|
26
19
|
```
|
|
27
20
|
|
|
28
|
-
|
|
21
|
+
```bash
|
|
22
|
+
bun install viem @rhinestone/sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quickstart
|
|
26
|
+
|
|
27
|
+
You'll need a Rhinestone API key, as well as an existing account with some testnet ETH on the source chain.
|
|
28
|
+
|
|
29
|
+
### Creating a Wallet
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
Let's create a smart account with a single owner:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { createRhinestoneAccount } from '@rhinestone/sdk'
|
|
32
35
|
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
|
|
36
|
+
import { baseSepolia, arbitrumSepolia, optimismSepolia } from 'viem/chains'
|
|
37
|
+
import {
|
|
38
|
+
Chain,
|
|
39
|
+
createPublicClient,
|
|
40
|
+
createWalletClient,
|
|
41
|
+
encodeFunctionData,
|
|
42
|
+
erc20Abi,
|
|
43
|
+
Hex,
|
|
44
|
+
http,
|
|
45
|
+
parseEther,
|
|
46
|
+
} from 'viem'
|
|
47
|
+
|
|
48
|
+
const fundingPrivateKey = process.env.FUNDING_PRIVATE_KEY
|
|
49
|
+
if (!fundingPrivateKey) {
|
|
50
|
+
throw new Error('FUNDING_PRIVATE_KEY is not set')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const rhinestoneApiKey = process.env.RHINESTONE_API_KEY
|
|
54
|
+
if (!rhinestoneApiKey) {
|
|
55
|
+
throw new Error('RHINESTONE_API_KEY is not set')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const sourceChain = baseSepolia
|
|
59
|
+
const targetChain = arbitrumSepolia
|
|
60
|
+
|
|
61
|
+
// You can use an existing PK here
|
|
62
|
+
const privateKey = generatePrivateKey()
|
|
63
|
+
console.info(`Owner private key: ${privateKey}`)
|
|
64
|
+
const account = privateKeyToAccount(privateKey)
|
|
33
65
|
|
|
34
|
-
// Create account with WebAuthn support
|
|
35
66
|
const rhinestoneAccount = await createRhinestoneAccount({
|
|
36
67
|
owners: {
|
|
37
|
-
type: '
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
rhinestoneApiKey: 'your-api-key'
|
|
68
|
+
type: 'ecdsa',
|
|
69
|
+
accounts: [account],
|
|
70
|
+
}
|
|
71
|
+
rhinestoneApiKey,
|
|
42
72
|
})
|
|
73
|
+
const address = await rhinestoneAccount.getAddress()
|
|
74
|
+
console.info(`Smart account address: ${address}`)
|
|
43
75
|
```
|
|
44
76
|
|
|
45
|
-
|
|
77
|
+
### Funding the Account
|
|
78
|
+
|
|
79
|
+
We will send some ETH from the funding account to the created smart account. The Orchestrator will use some of that ETH to deploy the account on the target chain, as well as to convert it to USDC for a transfer transaction.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const publicClient = createPublicClient({
|
|
83
|
+
chain: sourceChain,
|
|
84
|
+
transport: http(),
|
|
85
|
+
});
|
|
86
|
+
const fundingAccount = privateKeyToAccount(fundingPrivateKey as Hex);
|
|
87
|
+
const fundingClient = createWalletClient({
|
|
88
|
+
account: fundingAccount,
|
|
89
|
+
chain: sourceChain,
|
|
90
|
+
transport: http(),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const txHash = await fundingClient.sendTransaction({
|
|
94
|
+
to: address,
|
|
95
|
+
value: parseEther('0.001'),
|
|
96
|
+
});
|
|
97
|
+
await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
98
|
+
```
|
|
46
99
|
|
|
47
|
-
###
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
100
|
+
### Sending a Cross-chain Transaction
|
|
101
|
+
|
|
102
|
+
Finally, let's make a cross-chain token transfer:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const usdcTarget = '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d';
|
|
106
|
+
const usdcAmount = 1n;
|
|
107
|
+
|
|
108
|
+
const transaction = await rhinestoneAccount.sendTransaction({
|
|
109
|
+
sourceChain,
|
|
110
|
+
targetChain,
|
|
111
|
+
calls: [
|
|
112
|
+
{
|
|
113
|
+
to: usdcTarget,
|
|
114
|
+
value: 0n,
|
|
115
|
+
data: encodeFunctionData({
|
|
116
|
+
abi: erc20Abi,
|
|
117
|
+
functionName: 'transfer',
|
|
118
|
+
args: ['0xd8da6bf26964af9d7eed9e03e53415d37aa96045', usdcAmount],
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
tokenRequests: [
|
|
123
|
+
{
|
|
124
|
+
address: usdcTarget,
|
|
125
|
+
amount: usdcAmount,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
console.info('Transaction', transaction);
|
|
130
|
+
|
|
131
|
+
const transactionResult = await rhinestoneAccount.waitForExecution(transaction);
|
|
132
|
+
console.info('Result', transactionResult);
|
|
61
133
|
```
|
|
62
134
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
135
|
+
After running that, you will get a smart account deployed on both Base Sepolia and Arbitrum Sepolia, and make a cross-chain USDC transfer.
|
|
136
|
+
|
|
137
|
+
### Using Smart Sessions
|
|
138
|
+
|
|
139
|
+
First, define a session you want to use:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
const session: Session = {
|
|
67
143
|
owners: {
|
|
68
|
-
type: '
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
144
|
+
type: 'ecdsa',
|
|
145
|
+
accounts: [sessionOwner],
|
|
146
|
+
},
|
|
147
|
+
actions: [
|
|
148
|
+
{
|
|
149
|
+
target: wethAddress,
|
|
150
|
+
selector: toFunctionSelector(
|
|
151
|
+
getAbiItem({
|
|
152
|
+
abi: wethAbi,
|
|
153
|
+
name: 'deposit',
|
|
154
|
+
}),
|
|
155
|
+
),
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
target: wethAddress,
|
|
159
|
+
selector: toFunctionSelector(
|
|
160
|
+
getAbiItem({
|
|
161
|
+
abi: wethAbi,
|
|
162
|
+
name: 'transfer',
|
|
163
|
+
}),
|
|
164
|
+
),
|
|
165
|
+
policies: [
|
|
166
|
+
{
|
|
167
|
+
type: 'universal-action',
|
|
168
|
+
rules: [
|
|
169
|
+
{
|
|
170
|
+
condition: 'equal',
|
|
171
|
+
calldataOffset: 0n,
|
|
172
|
+
referenceValue: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
72
179
|
}
|
|
73
180
|
```
|
|
74
181
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
182
|
+
During account initialization, provide the session you've just created. Make sure to also provide a bundler configuration.
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
const rhinestoneAccount = await createRhinestoneAccount({
|
|
186
|
+
// …
|
|
187
|
+
sessions: [session],
|
|
188
|
+
bundler: {
|
|
189
|
+
// …
|
|
190
|
+
},
|
|
82
191
|
})
|
|
83
192
|
```
|
|
84
193
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# Install dependencies
|
|
89
|
-
bun install
|
|
194
|
+
When making a transaction, specify the `signers` object to sign it with the session key:
|
|
90
195
|
|
|
91
|
-
|
|
92
|
-
|
|
196
|
+
```ts
|
|
197
|
+
const transactionResult = await rhinestoneAccount.sendTransaction({
|
|
198
|
+
// …
|
|
199
|
+
signers: {
|
|
200
|
+
type: 'session',
|
|
201
|
+
session: session,
|
|
202
|
+
},
|
|
203
|
+
})
|
|
204
|
+
```
|
|
93
205
|
|
|
94
|
-
|
|
95
|
-
bun run test
|
|
206
|
+
## Migrating from Orchestrator SDK
|
|
96
207
|
|
|
97
|
-
|
|
98
|
-
bun run changeset
|
|
208
|
+
To migrate from the [Orchestrator SDK](https://github.com/rhinestonewtf/orchestrator-sdk), replace all imports of `@rhinestone/orchestrator-sdk` with `@rhinestone/sdk/orchestrator`.
|
|
99
209
|
|
|
100
|
-
|
|
101
|
-
bun run changeset:version
|
|
102
|
-
bun run changeset:release
|
|
103
|
-
```
|
|
210
|
+
Let us know if you encounter any issues!
|
|
104
211
|
|
|
105
|
-
##
|
|
212
|
+
## Contributing
|
|
106
213
|
|
|
107
|
-
|
|
214
|
+
For feature or change requests, feel free to open a PR, start a discussion or get in touch with us.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Chain, type HashTypedDataParameters, type Hex, type PublicClient, type TypedData } from 'viem';
|
|
2
2
|
import type { Module } from '../modules/common';
|
|
3
3
|
import type { EnableSessionData } from '../modules/validators/smart-sessions';
|
|
4
4
|
import type { AccountProviderConfig, Call, OwnerSet, RhinestoneAccountConfig, Session, SignerSet } from '../types';
|
|
@@ -17,12 +17,13 @@ declare function getModuleInstallationCalls(config: RhinestoneAccountConfig, mod
|
|
|
17
17
|
declare function getModuleUninstallationCalls(config: RhinestoneAccountConfig, module: Module): Call[];
|
|
18
18
|
declare function getAddress(config: RhinestoneAccountConfig): `0x${string}`;
|
|
19
19
|
declare function getPackedSignature(config: RhinestoneAccountConfig, signers: SignerSet | undefined, chain: Chain, validator: ValidatorConfig, hash: Hex, transformSignature?: (signature: Hex) => Hex): Promise<`0x${string}`>;
|
|
20
|
-
declare function
|
|
20
|
+
declare function getTypedDataPackedSignature<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData>(config: RhinestoneAccountConfig, signers: SignerSet | undefined, chain: Chain, validator: ValidatorConfig, parameters: HashTypedDataParameters<typedData, primaryType>, transformSignature?: (signature: Hex) => Hex): Promise<`0x${string}`>;
|
|
21
|
+
declare function isDeployed(config: RhinestoneAccountConfig, chain: Chain): Promise<boolean>;
|
|
21
22
|
declare function deploy(config: RhinestoneAccountConfig, chain: Chain, session?: Session): Promise<void>;
|
|
22
|
-
declare function
|
|
23
|
-
declare function getSmartAccount(config: RhinestoneAccountConfig, client: PublicClient, chain: Chain): Promise<import("viem/account-abstraction").SmartAccount<import("viem/account-abstraction").SmartAccountImplementation<import("viem").Abi, "0.7">>>;
|
|
24
|
-
declare function getSmartSessionSmartAccount(config: RhinestoneAccountConfig, client: PublicClient, chain: Chain, session: Session, enableData: EnableSessionData | null): Promise<import("viem/account-abstraction").SmartAccount<import("viem/account-abstraction").SmartAccountImplementation<import("viem").Abi, "0.7">>>;
|
|
25
|
-
declare function getGuardianSmartAccount(config: RhinestoneAccountConfig, client: PublicClient, chain: Chain, guardians: OwnerSet): Promise<import("viem/account-abstraction").SmartAccount<import("viem/account-abstraction").SmartAccountImplementation<import("viem").Abi, "0.7">>>;
|
|
23
|
+
declare function toErc6492Signature(config: RhinestoneAccountConfig, signature: Hex, chain: Chain): Promise<Hex>;
|
|
24
|
+
declare function getSmartAccount(config: RhinestoneAccountConfig, client: PublicClient, chain: Chain): Promise<import("viem/_types/account-abstraction").SmartAccount<import("viem/_types/account-abstraction").SmartAccountImplementation<import("viem").Abi, "0.7">>>;
|
|
25
|
+
declare function getSmartSessionSmartAccount(config: RhinestoneAccountConfig, client: PublicClient, chain: Chain, session: Session, enableData: EnableSessionData | null): Promise<import("viem/_types/account-abstraction").SmartAccount<import("viem/_types/account-abstraction").SmartAccountImplementation<import("viem").Abi, "0.7">>>;
|
|
26
|
+
declare function getGuardianSmartAccount(config: RhinestoneAccountConfig, client: PublicClient, chain: Chain, guardians: OwnerSet): Promise<import("viem/_types/account-abstraction").SmartAccount<import("viem/_types/account-abstraction").SmartAccountImplementation<import("viem").Abi, "0.7">>>;
|
|
26
27
|
declare function getAccountProvider(config: RhinestoneAccountConfig): AccountProviderConfig;
|
|
27
|
-
export { getModuleInstallationCalls, getModuleUninstallationCalls, getAddress, getAccountProvider, getInitCode, signEip7702InitData, getEip7702InitCall, isDeployed, deploy, getSmartAccount, getSmartSessionSmartAccount, getGuardianSmartAccount, getPackedSignature,
|
|
28
|
+
export { getModuleInstallationCalls, getModuleUninstallationCalls, getAddress, getAccountProvider, getInitCode, signEip7702InitData, getEip7702InitCall, isDeployed, deploy, toErc6492Signature, getSmartAccount, getSmartSessionSmartAccount, getGuardianSmartAccount, getPackedSignature, getTypedDataPackedSignature, isAccountError, AccountError, Eip7702AccountMustHaveEoaError, ExistingEip7702AccountsNotSupportedError, FactoryArgsNotAvailableError, SmartSessionsNotEnabledError, SigningNotSupportedForAccountError, SignMessageNotSupportedByAccountError, Eip7702NotSupportedForAccountError, };
|
|
28
29
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../accounts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../accounts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,15 +10,15 @@ exports.signEip7702InitData = signEip7702InitData;
|
|
|
10
10
|
exports.getEip7702InitCall = getEip7702InitCall;
|
|
11
11
|
exports.isDeployed = isDeployed;
|
|
12
12
|
exports.deploy = deploy;
|
|
13
|
+
exports.toErc6492Signature = toErc6492Signature;
|
|
13
14
|
exports.getSmartAccount = getSmartAccount;
|
|
14
15
|
exports.getSmartSessionSmartAccount = getSmartSessionSmartAccount;
|
|
15
16
|
exports.getGuardianSmartAccount = getGuardianSmartAccount;
|
|
16
17
|
exports.getPackedSignature = getPackedSignature;
|
|
17
|
-
exports.
|
|
18
|
+
exports.getTypedDataPackedSignature = getTypedDataPackedSignature;
|
|
18
19
|
const viem_1 = require("viem");
|
|
19
20
|
const execution_1 = require("../execution");
|
|
20
21
|
const smart_session_1 = require("../execution/smart-session");
|
|
21
|
-
const modules_1 = require("../modules");
|
|
22
22
|
const validators_1 = require("../modules/validators");
|
|
23
23
|
const core_1 = require("../modules/validators/core");
|
|
24
24
|
const error_1 = require("./error");
|
|
@@ -34,6 +34,9 @@ Object.defineProperty(exports, "SmartSessionsNotEnabledError", { enumerable: tru
|
|
|
34
34
|
const kernel_1 = require("./kernel");
|
|
35
35
|
const nexus_1 = require("./nexus");
|
|
36
36
|
const safe_1 = require("./safe");
|
|
37
|
+
const common_1 = require("./signing/common");
|
|
38
|
+
const message_1 = require("./signing/message");
|
|
39
|
+
const typedData_1 = require("./signing/typedData");
|
|
37
40
|
const startale_1 = require("./startale");
|
|
38
41
|
const utils_1 = require("./utils");
|
|
39
42
|
function getDeployArgs(config) {
|
|
@@ -179,26 +182,56 @@ function getAddress(config) {
|
|
|
179
182
|
}
|
|
180
183
|
// Signs and packs a signature to be EIP-1271 compatible
|
|
181
184
|
async function getPackedSignature(config, signers, chain, validator, hash, transformSignature = (signature) => signature) {
|
|
182
|
-
signers = signers ?? convertOwnerSetToSignerSet(config.owners);
|
|
183
|
-
const signFn = (hash) => sign(signers, chain, hash);
|
|
185
|
+
signers = signers ?? (0, common_1.convertOwnerSetToSignerSet)(config.owners);
|
|
186
|
+
const signFn = (hash) => (0, message_1.sign)(signers, chain, hash);
|
|
184
187
|
const account = getAccountProvider(config);
|
|
185
188
|
const address = getAddress(config);
|
|
186
189
|
switch (account.type) {
|
|
187
190
|
case 'safe': {
|
|
188
|
-
|
|
191
|
+
const signature = await signFn(hash);
|
|
192
|
+
return (0, safe_1.packSignature)(signature, validator, transformSignature);
|
|
189
193
|
}
|
|
190
194
|
case 'nexus': {
|
|
191
|
-
|
|
195
|
+
const signature = await signFn(hash);
|
|
196
|
+
return (0, nexus_1.packSignature)(signature, validator, transformSignature);
|
|
192
197
|
}
|
|
193
198
|
case 'kernel': {
|
|
194
|
-
|
|
199
|
+
const signature = await signFn((0, kernel_1.wrapMessageHash)(hash, address));
|
|
200
|
+
return (0, kernel_1.packSignature)(signature, validator, transformSignature);
|
|
195
201
|
}
|
|
196
202
|
case 'startale': {
|
|
197
|
-
|
|
203
|
+
const signature = await signFn(hash);
|
|
204
|
+
return (0, startale_1.packSignature)(signature, validator, transformSignature);
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
207
|
}
|
|
201
|
-
|
|
208
|
+
// Signs and packs a signature to be EIP-1271 compatible
|
|
209
|
+
async function getTypedDataPackedSignature(config, signers, chain, validator, parameters, transformSignature = (signature) => signature) {
|
|
210
|
+
signers = signers ?? (0, common_1.convertOwnerSetToSignerSet)(config.owners);
|
|
211
|
+
const signFn = (parameters) => (0, typedData_1.sign)(signers, chain, parameters);
|
|
212
|
+
const account = getAccountProvider(config);
|
|
213
|
+
switch (account.type) {
|
|
214
|
+
case 'safe': {
|
|
215
|
+
const signature = await signFn(parameters);
|
|
216
|
+
return (0, safe_1.packSignature)(signature, validator, transformSignature);
|
|
217
|
+
}
|
|
218
|
+
case 'nexus': {
|
|
219
|
+
const signature = await signFn(parameters);
|
|
220
|
+
return (0, nexus_1.packSignature)(signature, validator, transformSignature);
|
|
221
|
+
}
|
|
222
|
+
case 'kernel': {
|
|
223
|
+
const address = getAddress(config);
|
|
224
|
+
const signMessageFn = (hash) => (0, message_1.sign)(signers, chain, hash);
|
|
225
|
+
const signature = await signMessageFn((0, kernel_1.wrapMessageHash)((0, viem_1.hashTypedData)(parameters), address));
|
|
226
|
+
return (0, kernel_1.packSignature)(signature, validator, transformSignature);
|
|
227
|
+
}
|
|
228
|
+
case 'startale': {
|
|
229
|
+
const signature = await signFn(parameters);
|
|
230
|
+
return (0, startale_1.packSignature)(signature, validator, transformSignature);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
async function isDeployed(config, chain) {
|
|
202
235
|
const publicClient = (0, viem_1.createPublicClient)({
|
|
203
236
|
chain: chain,
|
|
204
237
|
transport: (0, utils_1.createTransport)(chain, config.provider),
|
|
@@ -233,7 +266,7 @@ async function deployWithIntent(chain, config) {
|
|
|
233
266
|
// Already deployed
|
|
234
267
|
return;
|
|
235
268
|
}
|
|
236
|
-
await (0, execution_1.sendTransaction)(config, {
|
|
269
|
+
const result = await (0, execution_1.sendTransaction)(config, {
|
|
237
270
|
targetChain: chain,
|
|
238
271
|
calls: [
|
|
239
272
|
{
|
|
@@ -242,42 +275,35 @@ async function deployWithIntent(chain, config) {
|
|
|
242
275
|
},
|
|
243
276
|
],
|
|
244
277
|
});
|
|
278
|
+
await (0, execution_1.waitForExecution)(config, result, true);
|
|
245
279
|
}
|
|
246
|
-
async function
|
|
247
|
-
|
|
248
|
-
|
|
280
|
+
async function toErc6492Signature(config, signature, chain) {
|
|
281
|
+
const deployed = await isDeployed(config, chain);
|
|
282
|
+
if (deployed) {
|
|
283
|
+
return signature;
|
|
249
284
|
}
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
if (
|
|
253
|
-
return address;
|
|
254
|
-
}
|
|
255
|
-
const { factory, factoryData } = getDeployArgs(config);
|
|
256
|
-
if (!factory || !factoryData) {
|
|
285
|
+
// Account is not deployed, use ERC-6492
|
|
286
|
+
const initCode = getInitCode(config);
|
|
287
|
+
if (!initCode) {
|
|
257
288
|
throw new error_1.FactoryArgsNotAvailableError();
|
|
258
289
|
}
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
to: factory,
|
|
270
|
-
data: factoryData,
|
|
271
|
-
});
|
|
272
|
-
await publicClient.waitForTransactionReceipt({ hash });
|
|
273
|
-
return address;
|
|
290
|
+
const { factory, factoryData } = initCode;
|
|
291
|
+
const magicBytes = '0x6492649264926492649264926492649264926492649264926492649264926492';
|
|
292
|
+
return (0, viem_1.concat)([
|
|
293
|
+
(0, viem_1.encodeAbiParameters)([
|
|
294
|
+
{ name: 'create2Factory', type: 'address' },
|
|
295
|
+
{ name: 'factoryCalldata', type: 'bytes' },
|
|
296
|
+
{ name: 'originalERC1271Signature', type: 'bytes' },
|
|
297
|
+
], [factory, factoryData, signature]),
|
|
298
|
+
magicBytes,
|
|
299
|
+
]);
|
|
274
300
|
}
|
|
275
301
|
async function getSmartAccount(config, client, chain) {
|
|
276
302
|
const account = getAccountProvider(config);
|
|
277
303
|
const address = getAddress(config);
|
|
278
304
|
const ownerValidator = (0, validators_1.getOwnerValidator)(config);
|
|
279
|
-
const signers = convertOwnerSetToSignerSet(config.owners);
|
|
280
|
-
const signFn = (hash) => sign(signers, chain, hash);
|
|
305
|
+
const signers = (0, common_1.convertOwnerSetToSignerSet)(config.owners);
|
|
306
|
+
const signFn = (hash) => (0, message_1.sign)(signers, chain, hash);
|
|
281
307
|
switch (account.type) {
|
|
282
308
|
case 'safe': {
|
|
283
309
|
return (0, safe_1.getSmartAccount)(client, address, config.owners, ownerValidator.address, signFn);
|
|
@@ -304,7 +330,7 @@ async function getSmartSessionSmartAccount(config, client, chain, session, enabl
|
|
|
304
330
|
session,
|
|
305
331
|
enableData: enableData || undefined,
|
|
306
332
|
};
|
|
307
|
-
const signFn = (hash) => sign(signers, chain, hash);
|
|
333
|
+
const signFn = (hash) => (0, message_1.sign)(signers, chain, hash);
|
|
308
334
|
const account = getAccountProvider(config);
|
|
309
335
|
switch (account.type) {
|
|
310
336
|
case 'safe': {
|
|
@@ -332,7 +358,7 @@ async function getGuardianSmartAccount(config, client, chain, guardians) {
|
|
|
332
358
|
type: 'guardians',
|
|
333
359
|
guardians: accounts,
|
|
334
360
|
};
|
|
335
|
-
const signFn = (hash) => sign(signers, chain, hash);
|
|
361
|
+
const signFn = (hash) => (0, message_1.sign)(signers, chain, hash);
|
|
336
362
|
const account = getAccountProvider(config);
|
|
337
363
|
switch (account.type) {
|
|
338
364
|
case 'safe': {
|
|
@@ -349,102 +375,6 @@ async function getGuardianSmartAccount(config, client, chain, guardians) {
|
|
|
349
375
|
}
|
|
350
376
|
}
|
|
351
377
|
}
|
|
352
|
-
async function sign(signers, chain, hash) {
|
|
353
|
-
switch (signers.type) {
|
|
354
|
-
case 'owner': {
|
|
355
|
-
switch (signers.kind) {
|
|
356
|
-
case 'ecdsa': {
|
|
357
|
-
const signatures = await Promise.all(signers.accounts.map((account) => signEcdsa(account, hash)));
|
|
358
|
-
return (0, viem_1.concat)(signatures);
|
|
359
|
-
}
|
|
360
|
-
case 'passkey': {
|
|
361
|
-
// Convert OwnerSignerSet to WebauthnValidatorConfig
|
|
362
|
-
const webAuthnConfig = {
|
|
363
|
-
type: 'passkey',
|
|
364
|
-
account: signers.account,
|
|
365
|
-
credentialIds: signers.credentialIds
|
|
366
|
-
};
|
|
367
|
-
return await signPasskey(webAuthnConfig, chain, hash);
|
|
368
|
-
}
|
|
369
|
-
case 'multi-factor': {
|
|
370
|
-
const signatures = await Promise.all(signers.validators.map(async (validator) => {
|
|
371
|
-
if (validator === null) {
|
|
372
|
-
return '0x';
|
|
373
|
-
}
|
|
374
|
-
// Convert to proper validator format
|
|
375
|
-
const validatorConfig = validator.type === 'ecdsa'
|
|
376
|
-
? { type: 'ecdsa', accounts: validator.accounts, threshold: 1 }
|
|
377
|
-
: { type: 'passkey', account: validator.account, credentialIds: validator.credentialIds };
|
|
378
|
-
const validatorSigners = convertOwnerSetToSignerSet(validatorConfig);
|
|
379
|
-
return sign(validatorSigners, chain, hash);
|
|
380
|
-
}));
|
|
381
|
-
const data = (0, viem_1.encodeAbiParameters)([
|
|
382
|
-
{
|
|
383
|
-
components: [
|
|
384
|
-
{
|
|
385
|
-
internalType: 'bytes32',
|
|
386
|
-
name: 'packedValidatorAndId',
|
|
387
|
-
type: 'bytes32',
|
|
388
|
-
},
|
|
389
|
-
{ internalType: 'bytes', name: 'data', type: 'bytes' },
|
|
390
|
-
],
|
|
391
|
-
name: 'validators',
|
|
392
|
-
type: 'tuple[]',
|
|
393
|
-
},
|
|
394
|
-
], [
|
|
395
|
-
signers.validators.map((validator, index) => {
|
|
396
|
-
// Convert to proper validator format for getValidator
|
|
397
|
-
const validatorConfig = validator.type === 'ecdsa'
|
|
398
|
-
? { type: 'ecdsa', accounts: validator.accounts, threshold: 1 }
|
|
399
|
-
: { type: 'passkey', account: validator.account, credentialIds: validator.credentialIds };
|
|
400
|
-
const validatorModule = (0, core_1.getValidator)(validatorConfig);
|
|
401
|
-
return {
|
|
402
|
-
packedValidatorAndId: (0, viem_1.concat)([
|
|
403
|
-
(0, viem_1.pad)((0, viem_1.toHex)(validator.id), { size: 12 }),
|
|
404
|
-
validatorModule.address,
|
|
405
|
-
]),
|
|
406
|
-
data: signatures[index],
|
|
407
|
-
};
|
|
408
|
-
}),
|
|
409
|
-
]);
|
|
410
|
-
return data;
|
|
411
|
-
}
|
|
412
|
-
default: {
|
|
413
|
-
throw new Error('Unsupported owner kind');
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
case 'session': {
|
|
418
|
-
const sessionSigners = convertOwnerSetToSignerSet(signers.session.owners);
|
|
419
|
-
return sign(sessionSigners, chain, hash);
|
|
420
|
-
}
|
|
421
|
-
case 'guardians': {
|
|
422
|
-
const signatures = await Promise.all(signers.guardians.map((account) => signEcdsa(account, hash)));
|
|
423
|
-
return (0, viem_1.concat)(signatures);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
async function signEcdsa(account, hash) {
|
|
428
|
-
if (!account.signMessage) {
|
|
429
|
-
throw new error_1.SigningNotSupportedForAccountError();
|
|
430
|
-
}
|
|
431
|
-
return await account.signMessage({ message: { raw: hash } });
|
|
432
|
-
}
|
|
433
|
-
async function signPasskey(validators, chain, hash) {
|
|
434
|
-
const { account, credentialIds } = validators;
|
|
435
|
-
console.log('credentialIds in the signPasskey', credentialIds);
|
|
436
|
-
const { webauthn: rawWebauthn, signature } = await account.sign({ hash });
|
|
437
|
-
console.log('rawWebauthn in the signPasskey', rawWebauthn);
|
|
438
|
-
console.log('signature in the signPasskey', signature);
|
|
439
|
-
const { authenticatorData, clientDataJSON, challengeIndex, typeIndex } = rawWebauthn;
|
|
440
|
-
const usePrecompiled = (0, modules_1.isRip7212SupportedNetwork)(chain);
|
|
441
|
-
return (0, modules_1.getWebauthnValidatorSignature)({
|
|
442
|
-
credentialIds,
|
|
443
|
-
usePrecompiled,
|
|
444
|
-
webauthn: { authenticatorData, clientDataJSON, challengeIndex, typeIndex },
|
|
445
|
-
signature,
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
378
|
function is7702(config) {
|
|
449
379
|
return config.eoa !== undefined;
|
|
450
380
|
}
|
|
@@ -456,40 +386,3 @@ function getAccountProvider(config) {
|
|
|
456
386
|
type: 'nexus',
|
|
457
387
|
};
|
|
458
388
|
}
|
|
459
|
-
function convertOwnerSetToSignerSet(owners) {
|
|
460
|
-
switch (owners.type) {
|
|
461
|
-
case 'ecdsa': {
|
|
462
|
-
return {
|
|
463
|
-
type: 'owner',
|
|
464
|
-
kind: 'ecdsa',
|
|
465
|
-
accounts: owners.accounts,
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
case 'passkey': {
|
|
469
|
-
const { account, credentialIds } = owners;
|
|
470
|
-
return {
|
|
471
|
-
type: 'owner',
|
|
472
|
-
kind: 'passkey',
|
|
473
|
-
account,
|
|
474
|
-
credentialIds,
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
case 'multi-factor': {
|
|
478
|
-
// Filter out null entries and propagate credentialIds
|
|
479
|
-
const mf = owners;
|
|
480
|
-
const validValidators = mf.validators.filter((v) => v !== null);
|
|
481
|
-
return {
|
|
482
|
-
type: 'owner',
|
|
483
|
-
kind: 'multi-factor',
|
|
484
|
-
validators: validValidators.map((validator, index) => {
|
|
485
|
-
if (validator.type === 'ecdsa') {
|
|
486
|
-
return { type: 'ecdsa', id: index, accounts: validator.accounts };
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
return { type: 'passkey', id: index, account: validator.account, credentialIds: validator.credentialIds };
|
|
490
|
-
}
|
|
491
|
-
}),
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|