@rhinestone/deposit-modal 0.1.26 → 0.1.28

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.
@@ -1,11 +1,9 @@
1
1
  import {
2
2
  CHAIN_BY_ID,
3
3
  NATIVE_TOKEN_ADDRESS,
4
- SUPPORTED_CHAINS,
5
4
  getChainIcon,
6
5
  getChainName,
7
6
  getExplorerTxUrl,
8
- getSupportedTokenSymbolsForChain,
9
7
  getTokenAddress,
10
8
  getTokenDecimalsByAddress,
11
9
  getTokenSymbol,
@@ -146,6 +144,71 @@ Modal.displayName = "Modal";
146
144
  function jsonReplacer(_key, value) {
147
145
  return typeof value === "bigint" ? value.toString() : value;
148
146
  }
147
+ function asRecord(value) {
148
+ return typeof value === "object" && value !== null ? value : null;
149
+ }
150
+ function toBigInt(value) {
151
+ if (typeof value === "bigint") return value;
152
+ if (typeof value === "number" && Number.isInteger(value)) return BigInt(value);
153
+ if (typeof value === "string" && value.trim() !== "") return BigInt(value);
154
+ throw new Error("Invalid bigint value");
155
+ }
156
+ function normalizeSessionTypedData(raw) {
157
+ const data = structuredClone(raw);
158
+ const domain = asRecord(data.domain);
159
+ if (domain && domain.chainId !== void 0 && domain.chainId !== null) {
160
+ domain.chainId = toBigInt(domain.chainId);
161
+ }
162
+ const message = asRecord(data.message);
163
+ if (!message || !Array.isArray(message.sessionsAndChainIds)) {
164
+ return data;
165
+ }
166
+ for (const entry of message.sessionsAndChainIds) {
167
+ const chainSession = asRecord(entry);
168
+ if (!chainSession) continue;
169
+ if (chainSession.chainId !== void 0 && chainSession.chainId !== null) {
170
+ chainSession.chainId = toBigInt(chainSession.chainId);
171
+ }
172
+ const session = asRecord(chainSession.session);
173
+ if (!session) continue;
174
+ if (session.nonce !== void 0 && session.nonce !== null) {
175
+ session.nonce = toBigInt(session.nonce);
176
+ }
177
+ if (session.expires !== void 0 && session.expires !== null) {
178
+ session.expires = toBigInt(session.expires);
179
+ }
180
+ }
181
+ return data;
182
+ }
183
+ function normalizeSetupAccountResponse(raw) {
184
+ const data = raw;
185
+ return {
186
+ smartAccount: data.smartAccount,
187
+ isRegistered: data.isRegistered,
188
+ targetChain: data.targetChain,
189
+ targetToken: data.targetToken,
190
+ needsRegistration: data.needsRegistration,
191
+ accountParams: data.accountParams,
192
+ sessionDetailsUnsigned: data.sessionDetailsUnsigned ? {
193
+ hashesAndChainIds: data.sessionDetailsUnsigned.hashesAndChainIds.map(
194
+ (h) => ({
195
+ chainId: toBigInt(h.chainId),
196
+ sessionDigest: h.sessionDigest
197
+ })
198
+ ),
199
+ data: normalizeSessionTypedData(data.sessionDetailsUnsigned.data)
200
+ } : void 0
201
+ };
202
+ }
203
+ function buildSessionDetails(unsigned, signature) {
204
+ return {
205
+ hashesAndChainIds: unsigned.hashesAndChainIds.map((h) => ({
206
+ chainId: toBigInt(h.chainId),
207
+ sessionDigest: h.sessionDigest
208
+ })),
209
+ signature
210
+ };
211
+ }
149
212
  function createDepositService(baseUrl) {
150
213
  const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
151
214
  function apiUrl(path) {
@@ -153,8 +216,8 @@ function createDepositService(baseUrl) {
153
216
  return `${normalizedBaseUrl}${normalizedPath}`;
154
217
  }
155
218
  return {
156
- async prepareAccount(params) {
157
- const response = await fetch(apiUrl("/prepare-account"), {
219
+ async setupAccount(params) {
220
+ const response = await fetch(apiUrl("/setup-account"), {
158
221
  method: "POST",
159
222
  headers: { "Content-Type": "application/json" },
160
223
  body: JSON.stringify(params)
@@ -162,10 +225,10 @@ function createDepositService(baseUrl) {
162
225
  if (!response.ok) {
163
226
  const error = await response.json().catch(() => ({ error: "Unknown error" }));
164
227
  throw new Error(
165
- error.error || `Prepare account failed: ${response.status}`
228
+ error.error || `Setup account failed: ${response.status}`
166
229
  );
167
230
  }
168
- return response.json();
231
+ return normalizeSetupAccountResponse(await response.json());
169
232
  },
170
233
  async registerAccount(params) {
171
234
  const { eoaAddress, sessionOwner, ...account } = params;
@@ -189,17 +252,6 @@ function createDepositService(baseUrl) {
189
252
  }
190
253
  return response.json();
191
254
  },
192
- async checkAccount(address) {
193
- const response = await fetch(apiUrl(`/check/${address}`), {
194
- method: "GET",
195
- headers: { "Content-Type": "application/json" }
196
- });
197
- if (!response.ok) {
198
- const error = await response.json().catch(() => ({ error: "Unknown error" }));
199
- throw new Error(error.error || `Check failed: ${response.status}`);
200
- }
201
- return response.json();
202
- },
203
255
  async fetchPortfolio(address) {
204
256
  const response = await fetch(apiUrl(`/portfolio/${address}`), {
205
257
  method: "GET",
@@ -817,203 +869,6 @@ function ConnectStep({
817
869
  }
818
870
  ConnectStep.displayName = "ConnectStep";
819
871
 
820
- // src/core/account.ts
821
- import {
822
- RhinestoneSDK
823
- } from "@rhinestone/sdk";
824
- import { zeroAddress } from "viem";
825
- import { toAccount } from "viem/accounts";
826
- function createViewOnlyAccount(address) {
827
- if (!address || address === zeroAddress) {
828
- throw new Error("Address is required");
829
- }
830
- return toAccount({
831
- address,
832
- signMessage: async () => {
833
- throw new Error("Account is view-only");
834
- },
835
- signTransaction: async () => {
836
- throw new Error("Account is view-only");
837
- },
838
- signTypedData: async () => {
839
- throw new Error("Account is view-only");
840
- }
841
- });
842
- }
843
- function getSessionSignerAccount(signerAddress) {
844
- if (!signerAddress || signerAddress === zeroAddress) {
845
- throw new Error("Signer address is required");
846
- }
847
- return toAccount({
848
- address: signerAddress,
849
- signMessage: async () => {
850
- throw new Error("Session signer is view-only");
851
- },
852
- signTransaction: async () => {
853
- throw new Error("Session signer is view-only");
854
- },
855
- signTypedData: async () => {
856
- throw new Error("Session signer is view-only");
857
- }
858
- });
859
- }
860
- function buildSession(chain, signerAddress) {
861
- const sessionSignerAccount = getSessionSignerAccount(signerAddress);
862
- return {
863
- owners: {
864
- type: "ecdsa",
865
- accounts: [sessionSignerAccount]
866
- },
867
- chain
868
- };
869
- }
870
- async function createSmartAccount(userSigner, sessionSigner, sdkApiKey) {
871
- const rhinestone = new RhinestoneSDK({
872
- apiKey: sdkApiKey ?? ""
873
- });
874
- const ownerAccounts = sessionSigner ? [userSigner, sessionSigner] : [userSigner];
875
- const config = {
876
- account: {
877
- type: "nexus"
878
- },
879
- owners: {
880
- type: "ecdsa",
881
- accounts: ownerAccounts,
882
- ...sessionSigner ? { threshold: 1 } : {}
883
- },
884
- experimental_sessions: {
885
- enabled: true
886
- }
887
- };
888
- const account = await rhinestone.createAccount(config);
889
- return account;
890
- }
891
- function getAccountAddress(account) {
892
- return account.getAddress();
893
- }
894
- function getAccountInitData(account) {
895
- const { factory, factoryData } = account.getInitData();
896
- if (!factory) {
897
- throw new Error("Account init data is not available");
898
- }
899
- return {
900
- factory,
901
- factoryData
902
- };
903
- }
904
- async function signEnableSessionWithOwner(rhinestoneAccount, sessionDetails, signer) {
905
- const originalOwners = rhinestoneAccount.config.owners;
906
- rhinestoneAccount.config.owners = {
907
- type: "ecdsa",
908
- accounts: [signer],
909
- threshold: 1,
910
- ...originalOwners?.type === "ecdsa" && originalOwners.module ? { module: originalOwners.module } : {}
911
- };
912
- try {
913
- return await rhinestoneAccount.experimental_signEnableSession(
914
- sessionDetails
915
- );
916
- } finally {
917
- rhinestoneAccount.config.owners = originalOwners;
918
- }
919
- }
920
- async function getSessionDetails(rhinestoneAccount, targetChain, signerAddress, sessionSigner, targetToken, sessionChainIds) {
921
- const isTargetTestnet = Boolean(targetChain.testnet);
922
- const chainsByNetworkType = SUPPORTED_CHAINS.filter(
923
- (chain) => Boolean(chain.testnet) === isTargetTestnet
924
- );
925
- const chainsById = new Map(
926
- chainsByNetworkType.map((chain) => [chain.id, chain])
927
- );
928
- let selectedChains = [...chainsByNetworkType];
929
- if (sessionChainIds && sessionChainIds.length > 0) {
930
- const selectedByCaller = [];
931
- for (const chainId of sessionChainIds) {
932
- const chain = chainsById.get(chainId);
933
- if (chain) {
934
- selectedByCaller.push(chain);
935
- }
936
- }
937
- if (selectedByCaller.length > 0) {
938
- selectedChains = selectedByCaller;
939
- }
940
- }
941
- if (targetToken) {
942
- const targetSymbol = getTokenSymbol(
943
- targetToken,
944
- targetChain.id
945
- ).toUpperCase();
946
- if (targetSymbol && targetSymbol !== "TOKEN") {
947
- const chainsForToken = selectedChains.filter(
948
- (chain) => getSupportedTokenSymbolsForChain(chain.id).includes(targetSymbol)
949
- );
950
- if (chainsForToken.length > 0) {
951
- selectedChains = chainsForToken;
952
- }
953
- }
954
- }
955
- if (!selectedChains.some((c) => c.id === targetChain.id)) {
956
- selectedChains.push(targetChain);
957
- }
958
- const uniqueChains = Array.from(
959
- new Map(selectedChains.map((chain) => [chain.id, chain])).values()
960
- );
961
- const sessions = uniqueChains.map(
962
- (chain) => buildSession(chain, signerAddress)
963
- );
964
- const sessionDetails = await rhinestoneAccount.experimental_getSessionDetails(sessions);
965
- const enableSignature = sessionSigner ? await signEnableSessionWithOwner(
966
- rhinestoneAccount,
967
- sessionDetails,
968
- sessionSigner
969
- ) : await rhinestoneAccount.experimental_signEnableSession(sessionDetails);
970
- if (!sessionDetails.hashesAndChainIds?.length) {
971
- throw new Error("Session details missing chain digests");
972
- }
973
- return {
974
- hashesAndChainIds: sessionDetails.hashesAndChainIds,
975
- signature: enableSignature
976
- };
977
- }
978
- function deserializeSessionData(raw) {
979
- const data = structuredClone(raw);
980
- const message = data.message;
981
- if (!message?.sessionsAndChainIds) return data;
982
- for (const entry of message.sessionsAndChainIds) {
983
- const chainSession = entry;
984
- chainSession.chainId = BigInt(chainSession.chainId);
985
- const session = chainSession.session;
986
- if (session) {
987
- session.nonce = BigInt(session.nonce);
988
- session.expires = BigInt(session.expires);
989
- }
990
- }
991
- return data;
992
- }
993
- async function signSessionDetails(rhinestoneAccount, sessionDetailsUnsigned, signer) {
994
- const data = deserializeSessionData(sessionDetailsUnsigned.data);
995
- const hashesAndChainIds = sessionDetailsUnsigned.hashesAndChainIds.map(
996
- (h) => ({
997
- chainId: BigInt(h.chainId),
998
- sessionDigest: h.sessionDigest
999
- })
1000
- );
1001
- const sessionDetails = {
1002
- nonces: [],
1003
- hashesAndChainIds,
1004
- data
1005
- };
1006
- const signature = await signEnableSessionWithOwner(
1007
- rhinestoneAccount,
1008
- sessionDetails,
1009
- signer
1010
- );
1011
- return {
1012
- hashesAndChainIds,
1013
- signature
1014
- };
1015
- }
1016
-
1017
872
  // src/core/session-owner.ts
1018
873
  import { isAddress } from "viem";
1019
874
  import {
@@ -1709,21 +1564,16 @@ export {
1709
1564
  Spinner,
1710
1565
  Button,
1711
1566
  ConnectStep,
1712
- createViewOnlyAccount,
1713
- createSmartAccount,
1714
- getAccountAddress,
1715
- getAccountInitData,
1716
- getSessionDetails,
1717
- signSessionDetails,
1567
+ buildSessionDetails,
1568
+ createDepositService,
1569
+ getAssetId,
1570
+ portfolioToAssets,
1571
+ isNativeAsset,
1718
1572
  loadSessionOwnerFromStorage,
1719
1573
  saveSessionOwnerToStorage,
1720
1574
  createSessionOwnerKey,
1721
1575
  accountFromPrivateKey,
1722
1576
  PoweredBy,
1723
- createDepositService,
1724
- getAssetId,
1725
- portfolioToAssets,
1726
- isNativeAsset,
1727
1577
  currencyFormatter,
1728
1578
  tokenFormatter,
1729
1579
  formatUserError,