@dynamic-labs/embedded-wallet-solana 3.0.0-alpha.8 → 3.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +622 -0
  2. package/package.cjs +22 -0
  3. package/package.js +17 -0
  4. package/package.json +15 -12
  5. package/src/lib/TurnkeySolanaWalletConnector/TurnkeySolanaSigner.cjs +4 -7
  6. package/src/lib/TurnkeySolanaWalletConnector/TurnkeySolanaSigner.d.ts +6 -5
  7. package/src/lib/TurnkeySolanaWalletConnector/TurnkeySolanaSigner.js +4 -7
  8. package/src/lib/TurnkeySolanaWalletConnector/TurnkeySolanaWalletConnector.cjs +138 -39
  9. package/src/lib/TurnkeySolanaWalletConnector/TurnkeySolanaWalletConnector.d.ts +16 -11
  10. package/src/lib/TurnkeySolanaWalletConnector/TurnkeySolanaWalletConnector.js +136 -37
  11. package/src/lib/utils/api/api.cjs +38 -0
  12. package/src/lib/utils/api/api.d.ts +4 -0
  13. package/src/lib/utils/api/api.js +32 -0
  14. package/src/lib/utils/api/events/DynamicEvents.d.ts +6 -0
  15. package/src/lib/utils/api/events/auth.d.ts +49 -0
  16. package/src/lib/utils/api/utils/ApiEndpoint.cjs +41 -0
  17. package/src/lib/utils/api/utils/ApiEndpoint.d.ts +7 -0
  18. package/src/lib/utils/api/utils/ApiEndpoint.js +39 -0
  19. package/src/lib/utils/api/utils/SdkApi.cjs +35 -0
  20. package/src/lib/utils/api/utils/SdkApi.d.ts +2 -0
  21. package/src/lib/utils/api/utils/SdkApi.js +31 -0
  22. package/src/lib/utils/api/utils/helpers.cjs +92 -0
  23. package/src/lib/utils/api/utils/helpers.d.ts +12 -0
  24. package/src/lib/utils/api/utils/helpers.js +81 -0
  25. package/src/lib/utils/api/utils/version.cjs +12 -0
  26. package/src/lib/utils/api/utils/version.d.ts +2 -0
  27. package/src/lib/utils/api/utils/version.js +7 -0
  28. package/src/lib/utils/index.d.ts +1 -2
  29. package/src/lib/utils/transactionDecoder/index.d.ts +1 -1
  30. package/src/lib/utils/transactionDecoder/transactionDecoder.cjs +127 -71
  31. package/src/lib/utils/transactionDecoder/transactionDecoder.d.ts +8 -6
  32. package/src/lib/utils/transactionDecoder/transactionDecoder.js +127 -72
  33. package/src/lib/constants.cjs +0 -8
  34. package/src/lib/constants.d.ts +0 -1
  35. package/src/lib/constants.js +0 -4
  36. package/src/lib/utils/getGenesisHashLSKey/getGenesisHashLSKey.cjs +0 -10
  37. package/src/lib/utils/getGenesisHashLSKey/getGenesisHashLSKey.d.ts +0 -1
  38. package/src/lib/utils/getGenesisHashLSKey/getGenesisHashLSKey.js +0 -6
  39. package/src/lib/utils/getGenesisHashLSKey/index.d.ts +0 -1
@@ -5,13 +5,13 @@ import { WebauthnStamper } from '@turnkey/webauthn-stamper';
5
5
  import { TurnkeyClient } from '@turnkey/http';
6
6
  import { TurnkeySigner } from '@turnkey/solana';
7
7
  import { IframeStamper } from '@turnkey/iframe-stamper';
8
- import { ProviderChain } from '@dynamic-labs/rpc-provider-solana';
8
+ import { isSameAddress } from '@dynamic-labs/wallet-connector-core';
9
9
  import { DynamicError, getTLD, PlatformService, bufferToBase64 } from '@dynamic-labs/utils';
10
- import { SolanaUiTransaction } from '@dynamic-labs/solana-utils';
11
- import { TurnkeyWalletConnectorBase, findTurnkeyVerifiedCredential, PasskeyService, TURNKEY_API_BASE_URL } from '@dynamic-labs/embedded-wallet';
10
+ import { SolanaWallet, ProviderChain, getGenesisHashLSKey, SolanaUiTransaction } from '@dynamic-labs/solana-core';
11
+ import { TurnkeyWalletConnectorBase, findTurnkeyVerifiedCredentials, PasskeyService, TURNKEY_API_BASE_URL, TURNKEY_SDK_SESSION_KEY_RETRYABLE_ERRORS, logger } from '@dynamic-labs/embedded-wallet';
12
12
  import { createSolanaConnection } from '../utils/createSolanaConnection/createSolanaConnection.js';
13
- import { getGenesisHashLSKey } from '../utils/getGenesisHashLSKey/getGenesisHashLSKey.js';
14
- import { decodeTransaction, summarizeTransactionDecodedData } from '../utils/transactionDecoder/transactionDecoder.js';
13
+ import { decodeTransaction, getTotalSolanaSpend, summarizeTransactionDecodedData } from '../utils/transactionDecoder/transactionDecoder.js';
14
+ import { optimizeSolanaTransaction } from '../utils/api/api.js';
15
15
  import { TurnkeySolanaSigner } from './TurnkeySolanaSigner.js';
16
16
 
17
17
  class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
@@ -19,9 +19,32 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
19
19
  var _a;
20
20
  super(nameAndKey, props);
21
21
  // Public fields
22
+ this.ChainWallet = SolanaWallet;
22
23
  this.connectedChain = 'SOL';
23
24
  this.supportedChains = ['SOL'];
24
25
  this.verifiedCredentialChain = 'solana';
26
+ this.getEnvId = () => {
27
+ const dynamicNonce = localStorage.getItem('dynamic_nonce');
28
+ if (dynamicNonce) {
29
+ const parsed = JSON.parse(dynamicNonce);
30
+ if (parsed && parsed.environmentId) {
31
+ return parsed.environmentId;
32
+ }
33
+ }
34
+ const dynamicNonceDemo = localStorage.getItem('dynamic_nonce_demo');
35
+ if (dynamicNonceDemo) {
36
+ const parsed = JSON.parse(dynamicNonceDemo);
37
+ if (parsed && parsed.environmentId) {
38
+ return parsed.environmentId;
39
+ }
40
+ }
41
+ throw new Error('Failed to get environment id');
42
+ };
43
+ this.stampCreateWalletAccountRequest = (_b) => __awaiter(this, [_b], void 0, function* ({ request, }) {
44
+ yield this.createOrRestoreSession();
45
+ const turnkeyClient = this.getTurnkeyClient();
46
+ return turnkeyClient.stampCreateWalletAccounts(request);
47
+ });
25
48
  this.solNetworks = props.solNetworks;
26
49
  this.walletUiUtils = props.walletUiUtils;
27
50
  this._turnkeyAccount = undefined;
@@ -92,15 +115,32 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
92
115
  return false;
93
116
  }
94
117
  setVerifiedCredentials(verifiedCredentials) {
95
- const turnkeyVerifiedCredential = findTurnkeyVerifiedCredential(verifiedCredentials, ProviderChain.SOLANA);
96
- const didTurnkeyVerifiedCredentialsChanged = JSON.stringify(this.verifiedCredential) !==
97
- JSON.stringify(turnkeyVerifiedCredential);
118
+ const turnkeyVerifiedCredentials = findTurnkeyVerifiedCredentials(verifiedCredentials, ProviderChain.SOLANA);
119
+ const [turnkeyVerifiedCredential] = turnkeyVerifiedCredentials;
120
+ const didTurnkeyVerifiedCredentialsChanged = JSON.stringify(this.verifiedCredentials) !==
121
+ JSON.stringify(turnkeyVerifiedCredentials);
98
122
  if (!didTurnkeyVerifiedCredentialsChanged) {
99
123
  return;
100
124
  }
101
125
  this.verifiedCredential = turnkeyVerifiedCredential;
126
+ this.verifiedCredentials = turnkeyVerifiedCredentials;
102
127
  this.refreshTurnkeyAccount();
103
128
  }
129
+ validateActiveWallet(expectedAddress) {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ var _a, _b;
132
+ const activeAddress = ((_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.address) || '';
133
+ const isWalletActive = isSameAddress(activeAddress, expectedAddress, this.connectedChain);
134
+ if (!isWalletActive) {
135
+ const targetActiveAccount = (_b = this.verifiedCredentials) === null || _b === void 0 ? void 0 : _b.find((vc) => (vc === null || vc === void 0 ? void 0 : vc.address) === expectedAddress);
136
+ if (!targetActiveAccount) {
137
+ throw new DynamicError('Account not found');
138
+ }
139
+ this.verifiedCredential = targetActiveAccount;
140
+ this.refreshTurnkeyAccount();
141
+ }
142
+ });
143
+ }
104
144
  getAccount() {
105
145
  return this.turnkeyAddress;
106
146
  }
@@ -158,23 +198,17 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
158
198
  this._turnkeyAccount = yield this.createTurnkeyAccount({
159
199
  organizationId: turnkeySubOrganizationId,
160
200
  });
201
+ this.setLoggerMetadata();
161
202
  return this._turnkeyAccount;
162
203
  });
163
204
  }
164
205
  getSigner() {
165
206
  return __awaiter(this, void 0, void 0, function* () {
166
- if (this.isSessionKeyCompatible()) {
167
- yield this.createOrRestoreSession();
168
- }
169
207
  return new TurnkeySolanaSigner({ walletConnector: this });
170
208
  });
171
209
  }
172
- getBalance() {
210
+ getBalance(address) {
173
211
  return __awaiter(this, void 0, void 0, function* () {
174
- const address = this.getAccount();
175
- if (!address) {
176
- return undefined;
177
- }
178
212
  const connectionClient = this.getConnection();
179
213
  const publicKey = new PublicKey(address);
180
214
  const balance = yield connectionClient.getBalance(publicKey);
@@ -182,34 +216,72 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
182
216
  return solBalance.toString();
183
217
  });
184
218
  }
185
- signMessage(messageToSign) {
219
+ signUint8ArrayMessage(encodedMessage) {
186
220
  return __awaiter(this, void 0, void 0, function* () {
187
221
  if (!this.turnkeyAddress) {
188
222
  throw new DynamicError('No turnkey account');
189
223
  }
190
224
  const address = this.turnkeyAddress;
191
- const signedMessage = yield this.walletUiUtils.signMessage({
225
+ let signedMessageRaw;
226
+ yield this.createOrRestoreSession();
227
+ yield this.walletUiUtils.signMessage({
192
228
  handler: () => __awaiter(this, void 0, void 0, function* () {
193
- var _a;
194
- const enc = new TextEncoder();
195
- const encodedMessage = enc.encode(messageToSign);
196
- const signedMessageRaw = yield ((_a = (yield this.getTurnkeyAccount())) === null || _a === void 0 ? void 0 : _a.signMessage(encodedMessage, address));
229
+ let account = yield this.getTurnkeyAccount();
230
+ try {
231
+ signedMessageRaw = yield (account === null || account === void 0 ? void 0 : account.signMessage(encodedMessage, address));
232
+ }
233
+ catch (_a) {
234
+ yield this.removeSessionKeys();
235
+ yield this.createOrRestoreSession({
236
+ ignoreRestore: true,
237
+ });
238
+ account = yield this.getTurnkeyAccount();
239
+ signedMessageRaw = yield (account === null || account === void 0 ? void 0 : account.signMessage(encodedMessage, address));
240
+ }
197
241
  return bufferToBase64(signedMessageRaw || Buffer.from([]));
198
242
  }),
199
- message: messageToSign,
243
+ message: new TextDecoder().decode(encodedMessage),
200
244
  });
201
- return signedMessage;
245
+ if (!signedMessageRaw) {
246
+ throw new Error('Failed to sign message');
247
+ }
248
+ return signedMessageRaw;
202
249
  });
203
250
  }
204
- signTransaction(_a) {
205
- return __awaiter(this, arguments, void 0, function* ({ transaction, }) {
206
- const account = yield this.getTurnkeyAccount();
251
+ signMessage(messageToSign) {
252
+ return __awaiter(this, void 0, void 0, function* () {
253
+ const enc = new TextEncoder();
254
+ const encodedMessage = enc.encode(messageToSign);
255
+ const signedRawMessage = yield this.signUint8ArrayMessage(encodedMessage);
256
+ return bufferToBase64(signedRawMessage);
257
+ });
258
+ }
259
+ signTransaction(transaction) {
260
+ return __awaiter(this, void 0, void 0, function* () {
261
+ yield this.createOrRestoreSession();
262
+ let account = yield this.getTurnkeyAccount();
207
263
  const address = this.turnkeyAddress;
208
264
  if (!account || !address) {
209
265
  throw new Error('No turnkey account');
210
266
  }
211
- yield account.addSignature(transaction, address);
212
- return Buffer.from(transaction.serialize());
267
+ try {
268
+ yield account.addSignature(transaction, address);
269
+ }
270
+ catch (err) {
271
+ if (TURNKEY_SDK_SESSION_KEY_RETRYABLE_ERRORS.some((errorMsg) => err.message.includes(errorMsg))) {
272
+ yield this.removeSessionKeys();
273
+ yield this.createOrRestoreSession({
274
+ ignoreRestore: true,
275
+ });
276
+ account = (yield this.getTurnkeyAccount());
277
+ yield account.addSignature(transaction, address);
278
+ }
279
+ else {
280
+ logger.error('[TK] failed to perform SignTransaction activity', err);
281
+ throw err;
282
+ }
283
+ }
284
+ return transaction;
213
285
  });
214
286
  }
215
287
  internalSignAndSendTransaction(transaction, options) {
@@ -228,8 +300,8 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
228
300
  transaction.feePayer =
229
301
  (_a = transaction.feePayer) !== null && _a !== void 0 ? _a : new PublicKey(this.turnkeyAddress);
230
302
  }
231
- const signedTransaction = yield this.signTransaction({ transaction });
232
- const signature = yield currentConnection.sendRawTransaction(signedTransaction, options);
303
+ const signedTransaction = yield this.signTransaction(transaction);
304
+ const signature = yield currentConnection.sendRawTransaction(Buffer.from(signedTransaction.serialize()), options);
233
305
  // listen for tx confirmation until 60 seconds, which is ~150 blocks expiration
234
306
  return new Promise((resolve, reject) => {
235
307
  const timeout = setTimeout(() => {
@@ -249,21 +321,45 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
249
321
  }
250
322
  signAndSendTransaction(transaction, options) {
251
323
  return __awaiter(this, void 0, void 0, function* () {
324
+ var _a;
252
325
  if (!this.turnkeyAddress)
253
326
  throw new DynamicError('Solana wallet not found');
254
- const transactionsData = yield decodeTransaction(transaction, this.getConnection(), this.turnkeyAddress);
327
+ let optimizedTransaction = transaction;
328
+ try {
329
+ if ((yield this.getNetwork()) === 'mainnet') {
330
+ optimizedTransaction = (yield optimizeSolanaTransaction(this.getEnvId(), transaction, (_a = this.turnkeyAddress) !== null && _a !== void 0 ? _a : ''));
331
+ }
332
+ }
333
+ catch (e) {
334
+ logger.warn('Failed to optimize transaction', e);
335
+ }
336
+ const transactionsData = yield decodeTransaction(optimizedTransaction, this.getConnection(), this.turnkeyAddress);
255
337
  if (!(transactionsData === null || transactionsData === void 0 ? void 0 : transactionsData.length)) {
256
338
  throw new DynamicError('Incorrectly formatted transaction instructions');
257
339
  }
258
- const { to, value } = summarizeTransactionDecodedData(transactionsData);
340
+ let spent;
341
+ let insufficientFunds = false;
342
+ try {
343
+ spent = yield getTotalSolanaSpend(optimizedTransaction, this.getConnection(), this.turnkeyAddress);
344
+ }
345
+ catch (e) {
346
+ if (e.message === 'Insufficient funds') {
347
+ insufficientFunds = true;
348
+ }
349
+ }
350
+ const to = summarizeTransactionDecodedData(transactionsData);
259
351
  const uiTransaction = new SolanaUiTransaction({
260
352
  connection: this.getConnection(),
261
353
  from: this.turnkeyAddress,
262
- onSubmit: () => __awaiter(this, void 0, void 0, function* () { return this.internalSignAndSendTransaction(transaction, options); }),
263
- originalTransaction: transaction,
354
+ onSubmit: () => __awaiter(this, void 0, void 0, function* () { return this.internalSignAndSendTransaction(optimizedTransaction, options); }),
355
+ originalTransaction: optimizedTransaction,
264
356
  });
265
357
  uiTransaction.to = to;
266
- uiTransaction.value = value;
358
+ uiTransaction.value = spent;
359
+ if (insufficientFunds) {
360
+ uiTransaction.notEnoughFundsError = true;
361
+ }
362
+ // TODO: remove this. We should not be passing references to wallet connectors
267
363
  return this.walletUiUtils.sendTransaction(this, uiTransaction);
268
364
  });
269
365
  }
@@ -307,11 +403,14 @@ class TurnkeySolanaWalletConnector extends TurnkeyWalletConnectorBase {
307
403
  }
308
404
  createUiTransaction(from) {
309
405
  return __awaiter(this, void 0, void 0, function* () {
310
- return new SolanaUiTransaction({
406
+ yield this.validateActiveWallet(from);
407
+ const transaction = new SolanaUiTransaction({
311
408
  connection: this.getConnection(),
312
409
  from,
313
410
  onSubmit: (transaction) => __awaiter(this, void 0, void 0, function* () { return this.internalSignAndSendTransaction(transaction); }),
314
411
  });
412
+ transaction.feeDeducted = true;
413
+ return transaction;
315
414
  });
316
415
  }
317
416
  }
@@ -0,0 +1,38 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../_virtual/_tslib.cjs');
7
+ var web3_js = require('@solana/web3.js');
8
+ var SdkApi = require('./utils/SdkApi.cjs');
9
+
10
+ const serializeTransaction = (transaction) => {
11
+ if (transaction instanceof web3_js.VersionedTransaction) {
12
+ return Buffer.from(transaction.serialize()).toString('base64');
13
+ }
14
+ else {
15
+ return Buffer.from(transaction.serialize({ verifySignatures: false })).toString('base64');
16
+ }
17
+ };
18
+ const deserializeTransaction = (serializedTransaction) => {
19
+ const transactionBuffer = Buffer.from(serializedTransaction, 'base64');
20
+ return web3_js.VersionedTransaction.deserialize(transactionBuffer);
21
+ };
22
+ const optimizeSolanaTransaction = (environmentId, transaction, address) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
23
+ const serializedTransaction = serializeTransaction(transaction);
24
+ const request = {
25
+ environmentId,
26
+ solanaTransactionOptimizationRequest: {
27
+ address,
28
+ transaction: serializedTransaction,
29
+ },
30
+ };
31
+ const response = yield SdkApi.sdkApi().optimizeTransaction(request);
32
+ const optimizedTransaction = deserializeTransaction(response.transaction);
33
+ return optimizedTransaction;
34
+ });
35
+
36
+ exports.deserializeTransaction = deserializeTransaction;
37
+ exports.optimizeSolanaTransaction = optimizeSolanaTransaction;
38
+ exports.serializeTransaction = serializeTransaction;
@@ -0,0 +1,4 @@
1
+ import { Transaction, VersionedTransaction } from '@solana/web3.js';
2
+ export declare const serializeTransaction: (transaction: Transaction | VersionedTransaction) => string;
3
+ export declare const deserializeTransaction: (serializedTransaction: string) => VersionedTransaction;
4
+ export declare const optimizeSolanaTransaction: (environmentId: string, transaction: Transaction | VersionedTransaction, address: string) => Promise<VersionedTransaction>;
@@ -0,0 +1,32 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../_virtual/_tslib.js';
3
+ import { VersionedTransaction } from '@solana/web3.js';
4
+ import { sdkApi } from './utils/SdkApi.js';
5
+
6
+ const serializeTransaction = (transaction) => {
7
+ if (transaction instanceof VersionedTransaction) {
8
+ return Buffer.from(transaction.serialize()).toString('base64');
9
+ }
10
+ else {
11
+ return Buffer.from(transaction.serialize({ verifySignatures: false })).toString('base64');
12
+ }
13
+ };
14
+ const deserializeTransaction = (serializedTransaction) => {
15
+ const transactionBuffer = Buffer.from(serializedTransaction, 'base64');
16
+ return VersionedTransaction.deserialize(transactionBuffer);
17
+ };
18
+ const optimizeSolanaTransaction = (environmentId, transaction, address) => __awaiter(void 0, void 0, void 0, function* () {
19
+ const serializedTransaction = serializeTransaction(transaction);
20
+ const request = {
21
+ environmentId,
22
+ solanaTransactionOptimizationRequest: {
23
+ address,
24
+ transaction: serializedTransaction,
25
+ },
26
+ };
27
+ const response = yield sdkApi().optimizeTransaction(request);
28
+ const optimizedTransaction = deserializeTransaction(response.transaction);
29
+ return optimizedTransaction;
30
+ });
31
+
32
+ export { deserializeTransaction, optimizeSolanaTransaction, serializeTransaction };
@@ -0,0 +1,6 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { AuthEvents } from './auth';
3
+ /** Maps internal event names to their listeners */
4
+ export type DynamicEvents = AuthEvents;
5
+ export declare const dynamicEvents: EventEmitter<AuthEvents, any>;
6
+ export type DynamicEventEmitter = typeof dynamicEvents;
@@ -0,0 +1,49 @@
1
+ import { AuthMethod, AuthOptions } from '@dynamic-labs/types';
2
+ /**
3
+ * Maps auth methods to what property will be displayed under the "option" property of the event.
4
+ *
5
+ * Users will be able to access this data through the AuthOptions[K] type injection as well,
6
+ * but with the "option" property they will also have a standard way to access the auth method target.
7
+ */
8
+ type AuthEventPayloadOptionMap = {
9
+ wallet: AuthOptions['wallet']['connectorName'];
10
+ sms: AuthOptions['sms']['phone'];
11
+ email: AuthOptions['email']['email'];
12
+ social: AuthOptions['social']['provider'];
13
+ externalAuth: AuthOptions['externalAuth']['externalUserId'];
14
+ };
15
+ /** Payload of auth events that provide insight into which auth method was selected */
16
+ export type AuthEventPayload = {
17
+ [K in AuthMethod]: {
18
+ type: K;
19
+ option: AuthEventPayloadOptionMap[K];
20
+ } & AuthOptions[K];
21
+ }[AuthMethod];
22
+ export type AuthEvents = {
23
+ /**
24
+ * Informs an auth attempt failed.
25
+ * In general triggered when an error occurs or when user cancels out.
26
+ * For email/sms, specifically happens when users cancels the OTP verification.
27
+ */
28
+ authFailure: (method: AuthEventPayload,
29
+ /** Will be 'user-cancelled' when cancelled, or the error when there is an error */
30
+ reason: 'user-cancelled' | {
31
+ error: unknown;
32
+ }) => void;
33
+ /** Informs an auth attempt initialized, and provides insight into which auth option it is */
34
+ authInit: (method: AuthEventPayload) => void;
35
+ logout: () => void;
36
+ /**
37
+ * Emitted when the user succesfully completes an MFA challenge
38
+ */
39
+ mfaCompletionSuccess: (args: {
40
+ mfaToken?: string;
41
+ }) => void;
42
+ /**
43
+ * Emitted when there is an error verifiyng the MFA challenge
44
+ */
45
+ mfaCompletionFailure: (args: {
46
+ error: unknown;
47
+ }) => void;
48
+ };
49
+ export {};
@@ -0,0 +1,41 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
5
+
6
+ /* eslint-disable no-underscore-dangle */
7
+ class ApiEndpoint {
8
+ }
9
+ ApiEndpoint.getBaseUrl = () => {
10
+ if (!ApiEndpoint.__defined__) {
11
+ throw new Error('ApiEndpoint Base URL has not been initialized');
12
+ }
13
+ return ApiEndpoint.__baseUrl__;
14
+ };
15
+ ApiEndpoint.setBaseUrl = (baseUrlInput) => {
16
+ if (!ApiEndpoint.__defined__) {
17
+ if (!baseUrlInput) {
18
+ /**
19
+ * If the baseUrl is not provided, use the default baseUrl from the sdk-api package
20
+ */
21
+ ApiEndpoint.__baseUrl__ = new sdkApiCore.Configuration().basePath;
22
+ }
23
+ else {
24
+ ApiEndpoint.__baseUrl__ = baseUrlInput;
25
+ }
26
+ ApiEndpoint.__defined__ = true;
27
+ }
28
+ else if (!baseUrlInput && ApiEndpoint.__defined__) {
29
+ /**
30
+ * If for some reason (usually in local development), the setBaseUrl is called multiple times with undefined
31
+ * And we already have it defined, let's just assume it's a no-op
32
+ */
33
+ return;
34
+ }
35
+ else if (ApiEndpoint.__baseUrl__ !== baseUrlInput) {
36
+ throw new Error(`ApiEndpoint baseUrl is already set to ${ApiEndpoint.__baseUrl__}, cannot change it to ${baseUrlInput}`);
37
+ }
38
+ Object.freeze(ApiEndpoint);
39
+ };
40
+
41
+ module.exports = ApiEndpoint;
@@ -0,0 +1,7 @@
1
+ declare class ApiEndpoint {
2
+ private static __baseUrl__;
3
+ private static __defined__;
4
+ static getBaseUrl: () => string | undefined;
5
+ static setBaseUrl: (baseUrlInput?: string) => void;
6
+ }
7
+ export default ApiEndpoint;
@@ -0,0 +1,39 @@
1
+ 'use client'
2
+ import { Configuration } from '@dynamic-labs/sdk-api-core';
3
+
4
+ /* eslint-disable no-underscore-dangle */
5
+ class ApiEndpoint {
6
+ }
7
+ ApiEndpoint.getBaseUrl = () => {
8
+ if (!ApiEndpoint.__defined__) {
9
+ throw new Error('ApiEndpoint Base URL has not been initialized');
10
+ }
11
+ return ApiEndpoint.__baseUrl__;
12
+ };
13
+ ApiEndpoint.setBaseUrl = (baseUrlInput) => {
14
+ if (!ApiEndpoint.__defined__) {
15
+ if (!baseUrlInput) {
16
+ /**
17
+ * If the baseUrl is not provided, use the default baseUrl from the sdk-api package
18
+ */
19
+ ApiEndpoint.__baseUrl__ = new Configuration().basePath;
20
+ }
21
+ else {
22
+ ApiEndpoint.__baseUrl__ = baseUrlInput;
23
+ }
24
+ ApiEndpoint.__defined__ = true;
25
+ }
26
+ else if (!baseUrlInput && ApiEndpoint.__defined__) {
27
+ /**
28
+ * If for some reason (usually in local development), the setBaseUrl is called multiple times with undefined
29
+ * And we already have it defined, let's just assume it's a no-op
30
+ */
31
+ return;
32
+ }
33
+ else if (ApiEndpoint.__baseUrl__ !== baseUrlInput) {
34
+ throw new Error(`ApiEndpoint baseUrl is already set to ${ApiEndpoint.__baseUrl__}, cannot change it to ${baseUrlInput}`);
35
+ }
36
+ Object.freeze(ApiEndpoint);
37
+ };
38
+
39
+ export { ApiEndpoint as default };
@@ -0,0 +1,35 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
7
+ var utils = require('@dynamic-labs/utils');
8
+ var helpers = require('./helpers.cjs');
9
+ var ApiEndpoint = require('./ApiEndpoint.cjs');
10
+ var version = require('./version.cjs');
11
+
12
+ const sdkApi = () => {
13
+ const baseUrl = process.env.API_BASE_URL ||
14
+ process.env.NX_API_BASE_URL ||
15
+ 'https://app.dynamic.xyz/api/v0';
16
+ ApiEndpoint.setBaseUrl(baseUrl);
17
+ const settings = {
18
+ basePath: ApiEndpoint.getBaseUrl(),
19
+ headers: {
20
+ 'Content-Type': 'application/json',
21
+ },
22
+ };
23
+ const minJwt = helpers.getMinAuthToken();
24
+ if (minJwt) {
25
+ settings.headers.Authorization = `Bearer ${minJwt}`;
26
+ }
27
+ const credentials = helpers.isCookieEnabled()
28
+ ? 'include'
29
+ : undefined;
30
+ settings.headers['x-dyn-version'] = `WalletKit/${version.VERSION}`;
31
+ settings.headers['x-dyn-api-version'] = `API/${version.API_VERSION}`;
32
+ return new sdkApiCore.SDKApi(new sdkApiCore.Configuration(Object.assign(Object.assign({}, settings), { credentials, fetchApi: utils.FetchService.fetch })));
33
+ };
34
+
35
+ exports.sdkApi = sdkApi;
@@ -0,0 +1,2 @@
1
+ import { SDKApi } from '@dynamic-labs/sdk-api-core';
2
+ export declare const sdkApi: () => SDKApi;
@@ -0,0 +1,31 @@
1
+ 'use client'
2
+ import { SDKApi, Configuration } from '@dynamic-labs/sdk-api-core';
3
+ import { FetchService } from '@dynamic-labs/utils';
4
+ import { getMinAuthToken, isCookieEnabled } from './helpers.js';
5
+ import ApiEndpoint from './ApiEndpoint.js';
6
+ import { VERSION, API_VERSION } from './version.js';
7
+
8
+ const sdkApi = () => {
9
+ const baseUrl = process.env.API_BASE_URL ||
10
+ process.env.NX_API_BASE_URL ||
11
+ 'https://app.dynamic.xyz/api/v0';
12
+ ApiEndpoint.setBaseUrl(baseUrl);
13
+ const settings = {
14
+ basePath: ApiEndpoint.getBaseUrl(),
15
+ headers: {
16
+ 'Content-Type': 'application/json',
17
+ },
18
+ };
19
+ const minJwt = getMinAuthToken();
20
+ if (minJwt) {
21
+ settings.headers.Authorization = `Bearer ${minJwt}`;
22
+ }
23
+ const credentials = isCookieEnabled()
24
+ ? 'include'
25
+ : undefined;
26
+ settings.headers['x-dyn-version'] = `WalletKit/${VERSION}`;
27
+ settings.headers['x-dyn-api-version'] = `API/${API_VERSION}`;
28
+ return new SDKApi(new Configuration(Object.assign(Object.assign({}, settings), { credentials, fetchApi: FetchService.fetch })));
29
+ };
30
+
31
+ export { sdkApi };
@@ -0,0 +1,92 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
7
+ var logger$1 = require('@dynamic-labs/logger');
8
+ var utils = require('@dynamic-labs/utils');
9
+
10
+ const logger = new logger$1.Logger('DynamicSDK');
11
+ const AUTH_MIN_TOKEN = 'dynamic_min_authentication_token';
12
+ const AUTH_MIN_TOKEN_DEMO = 'dynamic_min_authentication_token_demo';
13
+ const isCookieEnabled = () => {
14
+ var _a, _b, _c, _d;
15
+ let securitySettings = (_a = utils.StorageService.getItem('dynamic_store')) !== null && _a !== void 0 ? _a : utils.StorageService.getItem('dynamic_store_demo');
16
+ securitySettings = (_b = securitySettings === null || securitySettings === void 0 ? void 0 : securitySettings.settings) === null || _b === void 0 ? void 0 : _b.security;
17
+ if (!securitySettings)
18
+ return false;
19
+ // client uses Dynamic cookies
20
+ const dynamicCookiesEnabled = (((_c = securitySettings.auth) === null || _c === void 0 ? void 0 : _c.storage) || []).includes(sdkApiCore.AuthStorageEnum.Cookie);
21
+ // BYO JWT client puts their non-Dynamic JWT in a cookie
22
+ const byoJwtCookieEnabled = Boolean((_d = securitySettings.externalAuth) === null || _d === void 0 ? void 0 : _d.cookieName);
23
+ // should return true for both of these scenarios
24
+ // because we also need to do `credentials: true` in api.ts when
25
+ // a byo jwt client sets their named cookie for their jwt and
26
+ // needs to send it to our backend
27
+ return dynamicCookiesEnabled || byoJwtCookieEnabled;
28
+ };
29
+ const parseToken = (token) => {
30
+ var _a;
31
+ if (!token)
32
+ return undefined;
33
+ const base64 = (_a = token.split('.')[1]) === null || _a === void 0 ? void 0 : _a.replace(/-/g, '+').replace(/_/g, '/');
34
+ const jsonPayload = base64 &&
35
+ decodeURIComponent(atob(base64)
36
+ .split('')
37
+ .map((c) => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)
38
+ .join(''));
39
+ return JSON.parse(jsonPayload);
40
+ };
41
+ const decodeMinJwt = (token) => {
42
+ try {
43
+ const json = parseToken(token);
44
+ if (!json)
45
+ return undefined;
46
+ return sdkApiCore.MinifiedDynamicJwtFromJSON(json);
47
+ }
48
+ catch (e) {
49
+ logger.error(e);
50
+ return undefined;
51
+ }
52
+ };
53
+ const getMinAuthToken = () => {
54
+ var _a;
55
+ if (typeof window === 'undefined')
56
+ return undefined;
57
+ const token = (_a = utils.StorageService.getItem(AUTH_MIN_TOKEN, {
58
+ priority: ['secureStorage', 'localStorage'],
59
+ })) !== null && _a !== void 0 ? _a : utils.StorageService.getItem(AUTH_MIN_TOKEN_DEMO, {
60
+ priority: ['secureStorage', 'localStorage'],
61
+ });
62
+ if (!token || isMinAuthTokenExpired(token))
63
+ return undefined;
64
+ return token;
65
+ };
66
+ const isMinAuthTokenExpired = (token) => {
67
+ const decoded = decodeMinJwt(token);
68
+ return isTokenExpired(decoded);
69
+ };
70
+ const isTokenExpired = (decoded) => {
71
+ if (!decoded) {
72
+ return true;
73
+ }
74
+ if (!decoded.exp) {
75
+ return true;
76
+ }
77
+ const expirationTime = new Date(decoded.exp * 1000).getTime();
78
+ const currentTime = new Date().getTime();
79
+ if (currentTime >= expirationTime) {
80
+ return true;
81
+ }
82
+ return false;
83
+ };
84
+
85
+ exports.AUTH_MIN_TOKEN = AUTH_MIN_TOKEN;
86
+ exports.AUTH_MIN_TOKEN_DEMO = AUTH_MIN_TOKEN_DEMO;
87
+ exports.decodeMinJwt = decodeMinJwt;
88
+ exports.getMinAuthToken = getMinAuthToken;
89
+ exports.isCookieEnabled = isCookieEnabled;
90
+ exports.isMinAuthTokenExpired = isMinAuthTokenExpired;
91
+ exports.logger = logger;
92
+ exports.parseToken = parseToken;