@rhinestone/sdk 0.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.
Files changed (39) hide show
  1. package/README.md +168 -0
  2. package/dist/example.d.ts +1 -0
  3. package/dist/example.d.ts.map +1 -0
  4. package/dist/example.js +129 -0
  5. package/dist/index.d.ts +11 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +20 -0
  8. package/dist/package.json +1 -0
  9. package/dist/services/account.d.ts +13 -0
  10. package/dist/services/account.d.ts.map +1 -0
  11. package/dist/services/account.js +127 -0
  12. package/dist/services/modules.d.ts +34 -0
  13. package/dist/services/modules.d.ts.map +1 -0
  14. package/dist/services/modules.js +174 -0
  15. package/dist/services/orchestrator/client.d.ts +30 -0
  16. package/dist/services/orchestrator/client.d.ts.map +1 -0
  17. package/dist/services/orchestrator/client.js +203 -0
  18. package/dist/services/orchestrator/consts.d.ts +6 -0
  19. package/dist/services/orchestrator/consts.d.ts.map +1 -0
  20. package/dist/services/orchestrator/consts.js +4 -0
  21. package/dist/services/orchestrator/error.d.ts +17 -0
  22. package/dist/services/orchestrator/error.d.ts.map +1 -0
  23. package/dist/services/orchestrator/error.js +25 -0
  24. package/dist/services/orchestrator/index.d.ts +8 -0
  25. package/dist/services/orchestrator/index.d.ts.map +1 -0
  26. package/dist/services/orchestrator/index.js +9 -0
  27. package/dist/services/orchestrator/types.d.ts +147 -0
  28. package/dist/services/orchestrator/types.d.ts.map +1 -0
  29. package/dist/services/orchestrator/types.js +6 -0
  30. package/dist/services/orchestrator/utils.d.ts +7 -0
  31. package/dist/services/orchestrator/utils.d.ts.map +1 -0
  32. package/dist/services/orchestrator/utils.js +196 -0
  33. package/dist/services/transaction.d.ts +6 -0
  34. package/dist/services/transaction.d.ts.map +1 -0
  35. package/dist/services/transaction.js +93 -0
  36. package/dist/types.d.ts +45 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +1 -0
  39. package/package.json +43 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../services/orchestrator/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,GAAG,EAGJ,MAAM,MAAM,CAAA;AAGb,OAAO,EACL,WAAW,EAEX,iBAAiB,EAIlB,MAAM,SAAS,CAAA;AAYhB,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,GAAG,GAAG,CAMtE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAwBjD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,GAAG,GAAG,iBAAiB,CAiCrE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,GAAG,GAAG,WAAW,CAkClE"}
@@ -0,0 +1,196 @@
1
+ import { domainSeparator, encodeAbiParameters, encodePacked, keccak256, } from 'viem';
2
+ import { HOOK_ADDRESS } from './consts';
3
+ const MULTICHAIN_COMPACT_TYPEHASH = '0xee54591377b86e048be6b2fbd8913598a6270aed3415776321279495bf4efae5';
4
+ const SEGMENT_TYPEHASH = '0x54ada5b33a7390e2883c985295cfa2dcd9bb46515ad10cbdfc22a7c73f9807db';
5
+ const WITNESS_TYPEHASH = '0x78e29a727cef567e7d6dddf5bf7eedf0c84af60d4a57512c586c787aae731629';
6
+ const EXECUTION_TYPEHASH = '0xa222cbaaad3b88446c3ca031429dafb24afdbda10c5dbd9882c294762857141a';
7
+ export function getOrderBundleHash(orderBundle) {
8
+ const notarizedChainId = Number(orderBundle.segments[0].chainId);
9
+ return hashMultiChainCompactWithDomainSeparator(orderBundle, getCompactDomainSeparator(notarizedChainId, HOOK_ADDRESS));
10
+ }
11
+ export function convertBigIntFields(obj) {
12
+ if (obj === null || obj === undefined) {
13
+ return obj;
14
+ }
15
+ if (typeof obj === 'bigint') {
16
+ return obj.toString();
17
+ }
18
+ if (Array.isArray(obj)) {
19
+ return obj.map(convertBigIntFields);
20
+ }
21
+ if (typeof obj === 'object') {
22
+ const result = {};
23
+ for (const key in obj) {
24
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
25
+ result[key] = convertBigIntFields(obj[key]);
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ return obj;
31
+ }
32
+ export function parseCompactResponse(response) {
33
+ return {
34
+ sponsor: response.sponsor,
35
+ nonce: BigInt(response.nonce),
36
+ expires: BigInt(response.expires),
37
+ segments: response.segments.map((segment) => {
38
+ return {
39
+ arbiter: segment.arbiter,
40
+ chainId: BigInt(segment.chainId),
41
+ idsAndAmounts: segment.idsAndAmounts.map((idsAndAmount) => {
42
+ return [BigInt(idsAndAmount[0]), BigInt(idsAndAmount[1])];
43
+ }),
44
+ witness: {
45
+ recipient: segment.witness.recipient,
46
+ tokenOut: segment.witness.tokenOut.map((tokenOut) => {
47
+ return [BigInt(tokenOut[0]), BigInt(tokenOut[1])];
48
+ }),
49
+ depositId: BigInt(segment.witness.depositId),
50
+ targetChain: BigInt(segment.witness.targetChain),
51
+ fillDeadline: segment.witness.fillDeadline,
52
+ execs: segment.witness.execs.map((exec) => {
53
+ return {
54
+ to: exec.to,
55
+ value: BigInt(exec.value),
56
+ data: exec.data,
57
+ };
58
+ }),
59
+ userOpHash: segment.witness.userOpHash,
60
+ maxFeeBps: segment.witness.maxFeeBps,
61
+ },
62
+ };
63
+ }),
64
+ };
65
+ }
66
+ export function parsePendingBundleEvent(response) {
67
+ return {
68
+ type: response.type,
69
+ bundleId: BigInt(response.bundleId),
70
+ targetFillPayload: {
71
+ to: response.targetFillPayload.to,
72
+ data: response.targetFillPayload.data,
73
+ value: BigInt(response.targetFillPayload.value),
74
+ chainId: response.targetFillPayload.chainId,
75
+ },
76
+ acrossDepositEvents: response.acrossDepositEvents.map((event) => {
77
+ return {
78
+ message: event.message,
79
+ depositId: BigInt(event.depositId),
80
+ depositor: event.depositor,
81
+ recipient: event.recipient,
82
+ inputToken: event.inputToken,
83
+ inputAmount: BigInt(event.inputAmount),
84
+ outputToken: event.outputToken,
85
+ fillDeadline: event.fillDeadline,
86
+ outputAmount: BigInt(event.outputAmount),
87
+ quoteTimestamp: event.quoteTimestamp,
88
+ exclusiveRelayer: event.exclusiveRelayer,
89
+ destinationChainId: event.destinationChainId,
90
+ originClaimPayload: {
91
+ to: event.originClaimPayload.to,
92
+ data: event.originClaimPayload.data,
93
+ value: BigInt(event.originClaimPayload.value),
94
+ chainId: event.originClaimPayload.chainId,
95
+ },
96
+ exclusivityDeadline: event.exclusivityDeadline,
97
+ };
98
+ }),
99
+ };
100
+ }
101
+ function hashMultiChainCompactWithDomainSeparator(multiChainCompact, domainSeparator) {
102
+ return keccak256(encodePacked(['string', 'bytes32', 'bytes32'], [
103
+ '\x19\x01',
104
+ domainSeparator,
105
+ hashMultichainCompactWithoutDomainSeparator(multiChainCompact),
106
+ ]));
107
+ }
108
+ function hashMultichainCompactWithoutDomainSeparator(multiChainCompact) {
109
+ return keccak256(encodeAbiParameters([
110
+ { name: 'typehash', type: 'bytes32' },
111
+ { name: 'sponsor', type: 'address' },
112
+ { name: 'nonce', type: 'uint256' },
113
+ { name: 'expires', type: 'uint256' },
114
+ { name: 'segments', type: 'bytes32' },
115
+ ], [
116
+ MULTICHAIN_COMPACT_TYPEHASH,
117
+ multiChainCompact.sponsor,
118
+ multiChainCompact.nonce,
119
+ multiChainCompact.expires,
120
+ hashSegments([...multiChainCompact.segments]),
121
+ ]));
122
+ }
123
+ function hashSegments(segment) {
124
+ return keccak256(encodePacked(['bytes32[]'], [segment.map(hashSegment)]));
125
+ }
126
+ function hashSegment(segment) {
127
+ return keccak256(encodeAbiParameters([
128
+ { name: 'typehash', type: 'bytes32' },
129
+ { name: 'arbiter', type: 'address' },
130
+ { name: 'chainId', type: 'uint256' },
131
+ { name: 'idsAndAmounts', type: 'bytes32' },
132
+ { name: 'witness', type: 'bytes32' },
133
+ ], [
134
+ SEGMENT_TYPEHASH,
135
+ segment.arbiter,
136
+ segment.chainId,
137
+ hashIdsAndAmounts(segment.idsAndAmounts),
138
+ hashWitness(segment.witness),
139
+ ]));
140
+ }
141
+ function hashWitness(witness) {
142
+ return keccak256(encodeAbiParameters([
143
+ { name: 'typehash', type: 'bytes32' },
144
+ { name: 'recipient', type: 'address' },
145
+ { name: 'tokenOut', type: 'bytes32' },
146
+ { name: 'depositId', type: 'uint256' },
147
+ { name: 'targetChain', type: 'uint256' },
148
+ { name: 'fillDeadline', type: 'uint32' },
149
+ { name: 'execs', type: 'bytes32' }, // Assuming XchainExec[] is complex
150
+ { name: 'userOpHash', type: 'bytes32' },
151
+ { name: 'maxFeeBps', type: 'uint32' },
152
+ ], [
153
+ WITNESS_TYPEHASH,
154
+ witness.recipient,
155
+ hashIdsAndAmounts(witness.tokenOut),
156
+ witness.depositId,
157
+ witness.targetChain,
158
+ witness.fillDeadline,
159
+ hashExecutionArray(witness.execs),
160
+ witness.userOpHash,
161
+ witness.maxFeeBps,
162
+ ]));
163
+ }
164
+ function getCompactDomainSeparator(chainId, verifyingContract) {
165
+ return domainSeparator({
166
+ domain: getCompactDomain(chainId, verifyingContract),
167
+ });
168
+ }
169
+ function getCompactDomain(chainId, verifyingContract) {
170
+ return {
171
+ name: 'The Compact',
172
+ version: '0',
173
+ chainId: chainId,
174
+ verifyingContract: verifyingContract,
175
+ };
176
+ }
177
+ function hashIdsAndAmounts(idsAndAmounts) {
178
+ return keccak256(encodePacked(['uint256[2][]'], [idsAndAmounts]));
179
+ }
180
+ function hashExecutionArray(executionArray) {
181
+ const hashes = executionArray.map(hashExecution);
182
+ return keccak256(encodePacked(['bytes32[]'], [hashes]));
183
+ }
184
+ function hashExecution(execution) {
185
+ return keccak256(encodeAbiParameters([
186
+ { name: 'typehash', type: 'bytes32' },
187
+ { name: 'target', type: 'address' },
188
+ { name: 'value', type: 'uint256' },
189
+ { name: 'callData', type: 'bytes32' },
190
+ ], [
191
+ EXECUTION_TYPEHASH,
192
+ execution.to,
193
+ execution.value,
194
+ keccak256(execution.data),
195
+ ]));
196
+ }
@@ -0,0 +1,6 @@
1
+ import { type BundleResult } from './orchestrator';
2
+ import { RhinestoneAccountConfig, Transaction } from '../types';
3
+ declare function sendTransactions(config: RhinestoneAccountConfig, transaction: Transaction): Promise<bigint>;
4
+ declare function waitForExecution(config: RhinestoneAccountConfig, id: bigint): Promise<BundleResult>;
5
+ export { sendTransactions, waitForExecution };
6
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../services/transaction.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,YAAY,EAQlB,MAAM,gBAAgB,CAAA;AAQvB,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAY,MAAM,UAAU,CAAA;AAEzE,iBAAe,gBAAgB,CAC7B,MAAM,EAAE,uBAAuB,EAC/B,WAAW,EAAE,WAAW,mBAiEzB;AAED,iBAAe,gBAAgB,CAAC,MAAM,EAAE,uBAAuB,EAAE,EAAE,EAAE,MAAM,yBAa1E;AAmCD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}
@@ -0,0 +1,93 @@
1
+ import { concat, encodePacked } from 'viem';
2
+ import { BUNDLE_STATUS_PENDING, BUNDLE_STATUS_FAILED, getOrchestrator, getOrderBundleHash, } from './orchestrator';
3
+ import { getAddress, getDeployArgs, isDeployed, deploy } from './account';
4
+ import { getValidator, getWebauthnValidatorSignature, isRip7212SupportedNetwork, } from './modules';
5
+ async function sendTransactions(config, transaction) {
6
+ const { sourceChain, targetChain, calls, tokenRequests } = transaction;
7
+ const isAccountDeployed = await isDeployed(sourceChain, config);
8
+ if (!isAccountDeployed) {
9
+ await deploy(config.deployerAccount, sourceChain, config);
10
+ }
11
+ const accountAddress = await getAddress(config);
12
+ const metaIntent = {
13
+ targetChainId: targetChain.id,
14
+ tokenTransfers: tokenRequests.map((tokenRequest) => ({
15
+ tokenAddress: tokenRequest.address,
16
+ amount: tokenRequest.amount,
17
+ })),
18
+ targetAccount: accountAddress,
19
+ targetExecutions: calls.map((call) => ({
20
+ value: call.value ?? 0n,
21
+ to: call.to,
22
+ data: call.data ?? '0x',
23
+ })),
24
+ };
25
+ const orchestrator = getOrchestrator(config.rhinestoneApiKey);
26
+ const orderPath = await orchestrator.getOrderPath(metaIntent, accountAddress);
27
+ orderPath[0].orderBundle.segments[0].witness.execs = [
28
+ ...orderPath[0].injectedExecutions,
29
+ ...metaIntent.targetExecutions,
30
+ ];
31
+ const orderBundleHash = getOrderBundleHash(orderPath[0].orderBundle);
32
+ const bundleSignature = await sign(config.owners, sourceChain, orderBundleHash);
33
+ const validatorModule = getValidator(config);
34
+ const packedSig = encodePacked(['address', 'bytes'], [validatorModule.address, bundleSignature]);
35
+ const signedOrderBundle = {
36
+ ...orderPath[0].orderBundle,
37
+ originSignatures: Array(orderPath[0].orderBundle.segments.length).fill(packedSig),
38
+ targetSignature: packedSig,
39
+ };
40
+ const { factory, factoryData } = await getDeployArgs(config);
41
+ if (!factory || !factoryData) {
42
+ throw new Error('Factory args not available');
43
+ }
44
+ const initCode = encodePacked(['address', 'bytes'], [factory, factoryData]);
45
+ const bundleResults = await orchestrator.postSignedOrderBundle([
46
+ {
47
+ signedOrderBundle,
48
+ initCode,
49
+ },
50
+ ]);
51
+ return bundleResults[0].bundleId;
52
+ }
53
+ async function waitForExecution(config, id) {
54
+ let bundleResult = null;
55
+ while (bundleResult === null ||
56
+ bundleResult.status === BUNDLE_STATUS_PENDING) {
57
+ const orchestrator = getOrchestrator(config.rhinestoneApiKey);
58
+ bundleResult = await orchestrator.getBundleStatus(id);
59
+ }
60
+ if (bundleResult.status === BUNDLE_STATUS_FAILED) {
61
+ throw new Error('Bundle failed');
62
+ }
63
+ return bundleResult;
64
+ }
65
+ async function sign(validators, chain, hash) {
66
+ switch (validators.type) {
67
+ case 'ecdsa': {
68
+ const signatures = await Promise.all(validators.accounts.map((account) => signEcdsa(account, hash)));
69
+ return concat(signatures);
70
+ }
71
+ case 'passkey': {
72
+ return await signPasskey(validators.account, chain, hash);
73
+ }
74
+ }
75
+ }
76
+ async function signEcdsa(account, hash) {
77
+ const sign = account.signMessage;
78
+ if (!sign) {
79
+ throw new Error('Signing not supported for the account');
80
+ }
81
+ return await sign({ message: { raw: hash } });
82
+ }
83
+ async function signPasskey(account, chain, hash) {
84
+ const { webauthn, signature } = await account.sign({ hash });
85
+ const usePrecompiled = isRip7212SupportedNetwork(chain);
86
+ const encodedSignature = getWebauthnValidatorSignature({
87
+ webauthn,
88
+ signature,
89
+ usePrecompiled,
90
+ });
91
+ return encodedSignature;
92
+ }
93
+ export { sendTransactions, waitForExecution };
@@ -0,0 +1,45 @@
1
+ import { Account, Address, Chain, Hex } from 'viem';
2
+ import { WebAuthnAccount } from 'viem/account-abstraction';
3
+ interface OwnableValidatorConfig {
4
+ type: 'ecdsa';
5
+ accounts: Account[];
6
+ threshold?: number;
7
+ }
8
+ interface WebauthnValidatorConfig {
9
+ type: 'passkey';
10
+ account: WebAuthnAccount;
11
+ }
12
+ type OwnerSet = OwnableValidatorConfig | WebauthnValidatorConfig;
13
+ interface RhinestoneAccountConfig {
14
+ account: {
15
+ type: 'safe';
16
+ };
17
+ owners: OwnerSet;
18
+ rhinestoneApiKey: string;
19
+ deployerAccount: Account;
20
+ provider?: {
21
+ type: 'alchemy';
22
+ apiKey: string;
23
+ };
24
+ bundler?: {
25
+ type: 'pimlico';
26
+ apiKey: string;
27
+ };
28
+ }
29
+ interface Call {
30
+ to: Address;
31
+ data?: Hex;
32
+ value?: bigint;
33
+ }
34
+ interface TokenRequest {
35
+ address: Address;
36
+ amount: bigint;
37
+ }
38
+ interface Transaction {
39
+ sourceChain: Chain;
40
+ targetChain: Chain;
41
+ calls: Call[];
42
+ tokenRequests: TokenRequest[];
43
+ }
44
+ export type { RhinestoneAccountConfig, Transaction, OwnerSet };
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,UAAU,sBAAsB;IAC9B,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,uBAAuB;IAC/B,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,eAAe,CAAA;CACzB;AAED,KAAK,QAAQ,GAAG,sBAAsB,GAAG,uBAAuB,CAAA;AAChE,UAAU,uBAAuB;IAC/B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,MAAM,EAAE,QAAQ,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,SAAS,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,SAAS,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,UAAU,IAAI;IACZ,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,WAAW;IACnB,WAAW,EAAE,KAAK,CAAA;IAClB,WAAW,EAAE,KAAK,CAAA;IAClB,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B;AAED,YAAY,EAAE,uBAAuB,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@rhinestone/sdk",
3
+ "version": "0.1.0",
4
+ "description": "End-to-end chain abstraction and modularity toolkit",
5
+ "author": {
6
+ "name": "Rhinestone",
7
+ "url": "https://rhinestone.wtf"
8
+ },
9
+ "keywords": [
10
+ "ethereum",
11
+ "rhinestone",
12
+ "sdk"
13
+ ],
14
+ "license": "MIT",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "import": "./dist/index.js",
20
+ "types": "./dist/index.d.ts"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "homepage": "https://docs.rhinestone.wtf/",
27
+ "bugs": {
28
+ "url": "https://github.com/rhinestonewtf/sdk/issues"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/rhinestonewtf/sdk.git"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "dependencies": {
38
+ "axios": "^1.7.0"
39
+ },
40
+ "peerDependencies": {
41
+ "viem": "^2.20.0"
42
+ }
43
+ }