@fystack/sdk 0.1.7 → 0.1.9

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.
@@ -22,6 +22,8 @@ interface APIEndpoints {
22
22
  getWalletAssets: (walletId: string) => string;
23
23
  getDepositAddress: (walletId: string, addressType: string) => string;
24
24
  rescanTransaction: () => string;
25
+ requestWithdrawal: (walletId: string) => string;
26
+ getWebhookPublicKey: (workspaceId: string) => string;
25
27
  }
26
28
  interface APIConfig {
27
29
  baseURL: string;
@@ -319,6 +321,15 @@ declare enum WalletRole {
319
321
  Signer = "wallet_signer",
320
322
  Viewer = "wallet_viewer"
321
323
  }
324
+ declare enum WithdrawalStatus {
325
+ Pending = "pending",
326
+ PendingApproval = "pending_approval",
327
+ Approved = "approved",
328
+ Rejected = "rejected",
329
+ Processing = "processing",
330
+ Completed = "completed",
331
+ Failed = "failed"
332
+ }
322
333
 
323
334
  interface APIResponse {
324
335
  data: any;
@@ -361,9 +372,9 @@ declare class APIService {
361
372
  constructor(credentials: APICredentials, environment: Environment);
362
373
  getWallets(workspaceId: string): Promise<WalletByWorkspaceResponse[]>;
363
374
  getWalletDetail(addressType?: AddressType, walletId?: string): Promise<WalletDetail>;
364
- requestSign(walletId: string, params: SignRequestParams): Promise<SignResponse>;
375
+ requestSign(walletId: string, params: SignRequestParams, options?: Record<string, string>): Promise<SignResponse>;
365
376
  getSignStatus(walletId: string, transactionId: string): Promise<SignatureStatusResponse>;
366
- signTransaction(walletId: string, body: Record<string, any>): Promise<SignResponse>;
377
+ signTransaction(walletId: string, body: Record<string, any>, options?: Record<string, string>): Promise<SignResponse>;
367
378
  getTransactionStatus(walletId: string, transactionId: string): Promise<TransactionStatusResponse>;
368
379
  createWallet(payload: CreateWalletPayload): Promise<CreateWalletResponse>;
369
380
  createCheckout(payload: CreateCheckoutPayload): Promise<CreateCheckoutResponse>;
@@ -382,6 +393,19 @@ declare class APIService {
382
393
  * @returns API response
383
394
  */
384
395
  rescanTransaction(params: RescanTransactionParams): Promise<void>;
396
+ /**
397
+ * Requests a withdrawal from a wallet
398
+ * @param walletId The wallet ID
399
+ * @param params Withdrawal parameters
400
+ * @returns Withdrawal response with auto_approved status and withdrawal details
401
+ */
402
+ requestWithdrawal(walletId: string, params: RequestWithdrawalParams): Promise<RequestWithdrawalResponse>;
403
+ /**
404
+ * Gets the webhook public key for a workspace
405
+ * @param workspaceId The workspace ID
406
+ * @returns Webhook public key response with base64 encoded ed25519 public key
407
+ */
408
+ getWebhookPublicKey(workspaceId: string): Promise<WebhookPublicKeyResponse>;
385
409
  }
386
410
  declare class PaymentService {
387
411
  private apiKey;
@@ -415,6 +439,13 @@ declare function transformRescanTransactionParams(data: RescanTransactionParams)
415
439
  tx_hash: string;
416
440
  network_id: string;
417
441
  };
442
+ declare function transformRequestWithdrawalParams(data: RequestWithdrawalParams): {
443
+ skip_balance_check?: boolean | undefined;
444
+ notes?: string | undefined;
445
+ asset_id: string;
446
+ amount: string;
447
+ recipient_address: string;
448
+ };
418
449
 
419
450
  declare class TransactionError extends Error {
420
451
  readonly code: string;
@@ -555,6 +586,57 @@ interface WalletByWorkspaceResponse {
555
586
  top_assets: TopAssets[];
556
587
  wallet_purpose: string;
557
588
  }
589
+ interface RequestWithdrawalParams {
590
+ assetId: string;
591
+ amount: string;
592
+ recipientAddress: string;
593
+ notes?: string;
594
+ skipBalanceCheck?: boolean;
595
+ }
596
+ interface WithdrawalApproval {
597
+ id: string;
598
+ user_id: string;
599
+ status: string;
600
+ created_at: string;
601
+ updated_at: string;
602
+ }
603
+ interface WithdrawalTransaction {
604
+ id: string;
605
+ hash?: string;
606
+ status: string;
607
+ created_at: string;
608
+ updated_at: string;
609
+ }
610
+ interface TxCategory {
611
+ id: string;
612
+ name: string;
613
+ }
614
+ interface Withdrawal {
615
+ id: string;
616
+ created_at: string;
617
+ updated_at: string;
618
+ amount: string;
619
+ status: WithdrawalStatus;
620
+ recipient_address: string;
621
+ notes?: string;
622
+ withdrawal_approvals: WithdrawalApproval[];
623
+ creator_id: string;
624
+ asset_id: string;
625
+ asset?: WalletAssetDetail;
626
+ wallet_id: string;
627
+ transaction_id?: string;
628
+ transaction?: WithdrawalTransaction;
629
+ asset_hold_id: string;
630
+ error_reason?: string;
631
+ categories?: TxCategory[];
632
+ }
633
+ interface RequestWithdrawalResponse {
634
+ auto_approved: boolean;
635
+ withdrawal: Withdrawal;
636
+ }
637
+ interface WebhookPublicKeyResponse {
638
+ public_key: string;
639
+ }
558
640
 
559
641
  interface SDKOptions {
560
642
  credentials: APICredentials;
@@ -611,6 +693,19 @@ declare class FystackSDK {
611
693
  * @returns Promise that resolves when the rescan is initiated
612
694
  */
613
695
  rescanTransaction(params: RescanTransactionParams): Promise<void>;
696
+ /**
697
+ * Requests a withdrawal from a wallet
698
+ * @param walletId The ID of the wallet to withdraw from
699
+ * @param params Withdrawal parameters including asset, amount, and recipient
700
+ * @returns Promise with withdrawal response including auto_approved status and withdrawal details
701
+ */
702
+ requestWithdrawal(walletId: string, params: RequestWithdrawalParams): Promise<RequestWithdrawalResponse>;
703
+ /**
704
+ * Gets the webhook public key for a workspace
705
+ * @param workspaceId The workspace ID
706
+ * @returns Promise with webhook public key (base64 encoded ed25519 public key)
707
+ */
708
+ getWebhookPublicKey(workspaceId: string): Promise<WebhookPublicKeyResponse>;
614
709
  }
615
710
 
616
711
  interface StatusPollerOptions {
@@ -646,10 +741,18 @@ declare class EtherSigner extends AbstractSigner {
646
741
  connect(provider: null | Provider): EtherSigner;
647
742
  private waitForSignature;
648
743
  private waitForTransactonStatus;
649
- signTransaction(tx: TransactionRequest): Promise<string>;
650
- sendTransaction(tx: TransactionRequest): Promise<TransactionResponse>;
651
- signMessage(message: string | Uint8Array): Promise<string>;
652
- signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string>;
744
+ signTransaction(tx: TransactionRequest, options?: {
745
+ idempotencyKey?: string;
746
+ }): Promise<string>;
747
+ sendTransaction(tx: TransactionRequest, options?: {
748
+ idempotencyKey?: string;
749
+ }): Promise<TransactionResponse>;
750
+ signMessage(message: string | Uint8Array, options?: {
751
+ idempotencyKey?: string;
752
+ }): Promise<string>;
753
+ signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>, options?: {
754
+ idempotencyKey?: string;
755
+ }): Promise<string>;
653
756
  }
654
757
 
655
758
  declare class SolanaSigner {
@@ -668,28 +771,36 @@ declare class SolanaSigner {
668
771
  * @param transaction Base64 encoded serialized transaction
669
772
  * @returns Signature as a base58 encoded string
670
773
  */
671
- signTransaction(transaction: string): Promise<string>;
774
+ signTransaction(transaction: string, options?: {
775
+ idempotencyKey?: string;
776
+ }): Promise<string>;
672
777
  /**
673
778
  * Signs a Solana message
674
779
  * @param message The message to sign (string or Uint8Array)
675
780
  * @returns Signature as a base58 encoded string
676
781
  */
677
- signMessage(message: string | Uint8Array): Promise<string>;
782
+ signMessage(message: string | Uint8Array, options?: {
783
+ idempotencyKey?: string;
784
+ }): Promise<string>;
678
785
  /**
679
786
  * Signs and sends a Solana transaction
680
787
  * @param transaction Base64 encoded serialized transaction
681
788
  * @returns Transaction signature
682
789
  */
683
- signAndSendTransaction(transaction: string): Promise<string>;
790
+ signAndSendTransaction(transaction: string, options?: {
791
+ idempotencyKey?: string;
792
+ }): Promise<string>;
684
793
  /**
685
794
  * Signs multiple Solana transactions
686
795
  * @param transactions Array of base64 encoded serialized transactions
687
796
  * @returns Array of signatures as base58 encoded strings
688
797
  */
689
- signAllTransactions(transactions: string[]): Promise<{
798
+ signAllTransactions(transactions: string[], options?: {
799
+ idempotencyKey?: string;
800
+ }): Promise<{
690
801
  transactions: string[];
691
802
  }>;
692
803
  private incorporateSignatureIntoTransaction;
693
804
  }
694
805
 
695
- export { type APIConfig, type APICredentials, type APIEndpoints, APIService, AddressType, type ApprovalInfo, type CreateWalletOptions, type CreateWalletPayload, type CreateWalletResponse, DEFAULT_POLLER_OPTIONS, type DepositAddressResponse, DestinationType, Environment, EtherSigner, FystackSDK, type HMACParams, PaymentService, type PaymentServiceParams, type RescanTransactionParams, type SDKOptions, type SignRequestParams, type SignResponse, type SignatureStatusResponse, SolanaSigner, StatusPoller, type StatusPollerOptions, type SweepTaskParams, type TopAssets, TransactionError, type TransactionStatusResponse, TxApprovalStatus, TxStatus, type WalletAsset, type WalletAssetDetail, type WalletAssetNetwork, type WalletByWorkspaceResponse, WalletCreationStatus, type WalletCreationStatusResponse, type WalletDetail, WalletPurpose, type WalletResponse, WalletRole, WalletType, type WebhookEvent, WebhookService, createAPI, get, post, transformCreateWalletPayload, transformRescanTransactionParams, transformWalletDetail };
806
+ export { type APIConfig, type APICredentials, type APIEndpoints, APIService, AddressType, type ApprovalInfo, type CreateWalletOptions, type CreateWalletPayload, type CreateWalletResponse, DEFAULT_POLLER_OPTIONS, type DepositAddressResponse, DestinationType, Environment, EtherSigner, FystackSDK, type HMACParams, PaymentService, type PaymentServiceParams, type RequestWithdrawalParams, type RequestWithdrawalResponse, type RescanTransactionParams, type SDKOptions, type SignRequestParams, type SignResponse, type SignatureStatusResponse, SolanaSigner, StatusPoller, type StatusPollerOptions, type SweepTaskParams, type TopAssets, TransactionError, type TransactionStatusResponse, TxApprovalStatus, type TxCategory, TxStatus, type WalletAsset, type WalletAssetDetail, type WalletAssetNetwork, type WalletByWorkspaceResponse, WalletCreationStatus, type WalletCreationStatusResponse, type WalletDetail, WalletPurpose, type WalletResponse, WalletRole, WalletType, type WebhookEvent, type WebhookPublicKeyResponse, WebhookService, type Withdrawal, type WithdrawalApproval, WithdrawalStatus, type WithdrawalTransaction, createAPI, get, post, transformCreateWalletPayload, transformRequestWithdrawalParams, transformRescanTransactionParams, transformWalletDetail };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fystack/sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Wallet SDK",
5
5
  "main": "dist/index.cjs",
6
6
  "types": "dist/types/index.d.ts",
package/src/api.ts CHANGED
@@ -13,7 +13,10 @@ import {
13
13
  WalletAsset,
14
14
  DepositAddressResponse,
15
15
  RescanTransactionParams,
16
- WalletByWorkspaceResponse
16
+ WalletByWorkspaceResponse,
17
+ RequestWithdrawalParams,
18
+ RequestWithdrawalResponse,
19
+ WebhookPublicKeyResponse
17
20
  } from './types'
18
21
  import {
19
22
  CreateCheckoutPayload,
@@ -69,7 +72,8 @@ async function composeAPIHeaders(
69
72
  credentials: APICredentials,
70
73
  httpMethod: string,
71
74
  apiEndpoint: string,
72
- body: Record<string, any> = {}
75
+ body: Record<string, any> = {},
76
+ headers?: Record<string, string>
73
77
  ): Promise<Record<string, string>> {
74
78
  if (!credentials.apiSecret || credentials.apiSecret === '') {
75
79
  // If APISecret is not provided, use authToken
@@ -94,13 +98,14 @@ async function composeAPIHeaders(
94
98
 
95
99
  const digest = await computeHMAC(credentials.apiSecret, params as Record<string, any>)
96
100
 
97
- const headers = {
101
+ const combinedHeaders = {
98
102
  'ACCESS-API-KEY': credentials.apiKey,
99
103
  'ACCESS-TIMESTAMP': String(currentTimestampInSeconds),
100
- 'ACCESS-SIGN': btoa(digest) // convert to base64
104
+ 'ACCESS-SIGN': btoa(digest), // convert to base64
105
+ ...(headers ?? {})
101
106
  }
102
107
 
103
- return headers
108
+ return combinedHeaders
104
109
  }
105
110
 
106
111
  export class APIService {
@@ -129,9 +134,13 @@ export class APIService {
129
134
  return transformWalletDetail(resp.data)
130
135
  }
131
136
 
132
- async requestSign(walletId: string, params: SignRequestParams): Promise<SignResponse> {
137
+ async requestSign(
138
+ walletId: string,
139
+ params: SignRequestParams,
140
+ options?: Record<string, string>
141
+ ): Promise<SignResponse> {
133
142
  const endpoint = this.API.endpoints.requestSign(walletId)
134
- const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, params)
143
+ const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, params, options)
135
144
  const response = await post(endpoint, params, headers)
136
145
  return response.data
137
146
  }
@@ -143,10 +152,14 @@ export class APIService {
143
152
  return response.data
144
153
  }
145
154
 
146
- async signTransaction(walletId: string, body: Record<string, any>): Promise<SignResponse> {
155
+ async signTransaction(
156
+ walletId: string,
157
+ body: Record<string, any>,
158
+ options?: Record<string, string>
159
+ ): Promise<SignResponse> {
147
160
  const startTime = Date.now()
148
161
  const endpoint = this.API.endpoints.signTransaction(walletId)
149
- const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, body)
162
+ const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, body, options)
150
163
  const response = await post(endpoint, body, headers)
151
164
  const elapsedTime = Date.now() - startTime
152
165
 
@@ -222,6 +235,35 @@ export class APIService {
222
235
  const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, transformedParams)
223
236
  await post(endpoint, transformedParams, headers)
224
237
  }
238
+
239
+ /**
240
+ * Requests a withdrawal from a wallet
241
+ * @param walletId The wallet ID
242
+ * @param params Withdrawal parameters
243
+ * @returns Withdrawal response with auto_approved status and withdrawal details
244
+ */
245
+ async requestWithdrawal(
246
+ walletId: string,
247
+ params: RequestWithdrawalParams
248
+ ): Promise<RequestWithdrawalResponse> {
249
+ const endpoint = this.API.endpoints.requestWithdrawal(walletId)
250
+ const transformedParams = transformRequestWithdrawalParams(params)
251
+ const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, transformedParams)
252
+ const response = await post(endpoint, transformedParams, headers)
253
+ return response.data
254
+ }
255
+
256
+ /**
257
+ * Gets the webhook public key for a workspace
258
+ * @param workspaceId The workspace ID
259
+ * @returns Webhook public key response with base64 encoded ed25519 public key
260
+ */
261
+ async getWebhookPublicKey(workspaceId: string): Promise<WebhookPublicKeyResponse> {
262
+ const endpoint = this.API.endpoints.getWebhookPublicKey(workspaceId)
263
+ const headers = await composeAPIHeaders(this.credentials, 'GET', endpoint)
264
+ const response = await get(endpoint, headers)
265
+ return response.data
266
+ }
225
267
  }
226
268
 
227
269
  export class PaymentService {
@@ -370,6 +412,16 @@ export function transformRescanTransactionParams(data: RescanTransactionParams)
370
412
  }
371
413
  }
372
414
 
415
+ export function transformRequestWithdrawalParams(data: RequestWithdrawalParams) {
416
+ return {
417
+ asset_id: data.assetId,
418
+ amount: data.amount,
419
+ recipient_address: data.recipientAddress,
420
+ ...(data.notes !== undefined && { notes: data.notes }),
421
+ ...(data.skipBalanceCheck !== undefined && { skip_balance_check: data.skipBalanceCheck })
422
+ }
423
+ }
424
+
373
425
  ;(BigInt.prototype as any).toJSON = function () {
374
426
  return this.toString()
375
427
  }
package/src/config.ts CHANGED
@@ -21,6 +21,8 @@ export interface APIEndpoints {
21
21
  getWalletAssets: (walletId: string) => string
22
22
  getDepositAddress: (walletId: string, addressType: string) => string
23
23
  rescanTransaction: () => string
24
+ requestWithdrawal: (walletId: string) => string
25
+ getWebhookPublicKey: (workspaceId: string) => string
24
26
  }
25
27
 
26
28
  const getBaseURL = (env: Environment): string => {
@@ -71,7 +73,9 @@ const createAPI = (env: Environment): APIConfig => {
71
73
  getWalletAssets: (walletId: string) => withBaseURL(`/wallets/${walletId}/assets`),
72
74
  getDepositAddress: (walletId: string, addressType: string) =>
73
75
  withBaseURL(`/wallets/${walletId}/deposit-address?address_type=${addressType}`),
74
- rescanTransaction: () => withBaseURL('/networks/rescan-transaction')
76
+ rescanTransaction: () => withBaseURL('/networks/rescan-transaction'),
77
+ requestWithdrawal: (walletId: string) => withBaseURL(`/wallets/${walletId}/request-withdrawal`),
78
+ getWebhookPublicKey: (workspaceId: string) => withBaseURL(`/workspaces/${workspaceId}/webhook-verification-key`)
75
79
  }
76
80
  }
77
81
  }
package/src/enum.ts CHANGED
@@ -50,3 +50,13 @@ export enum WalletRole {
50
50
  Signer = 'wallet_signer',
51
51
  Viewer = 'wallet_viewer'
52
52
  }
53
+
54
+ export enum WithdrawalStatus {
55
+ Pending = 'pending',
56
+ PendingApproval = 'pending_approval',
57
+ Approved = 'approved',
58
+ Rejected = 'rejected',
59
+ Processing = 'processing',
60
+ Completed = 'completed',
61
+ Failed = 'failed'
62
+ }
package/src/sdk.ts CHANGED
@@ -9,7 +9,10 @@ import {
9
9
  APICredentials,
10
10
  CreateWalletOptions,
11
11
  RescanTransactionParams,
12
- WalletByWorkspaceResponse
12
+ WalletByWorkspaceResponse,
13
+ RequestWithdrawalParams,
14
+ RequestWithdrawalResponse,
15
+ WebhookPublicKeyResponse
13
16
  } from './types'
14
17
  import { validateUUID } from './utils'
15
18
  import { AddressType, WalletCreationStatus, WalletType } from './enum'
@@ -183,4 +186,53 @@ export class FystackSDK {
183
186
 
184
187
  await this.apiService.rescanTransaction(params)
185
188
  }
189
+
190
+ /**
191
+ * Requests a withdrawal from a wallet
192
+ * @param walletId The ID of the wallet to withdraw from
193
+ * @param params Withdrawal parameters including asset, amount, and recipient
194
+ * @returns Promise with withdrawal response including auto_approved status and withdrawal details
195
+ */
196
+ async requestWithdrawal(
197
+ walletId: string,
198
+ params: RequestWithdrawalParams
199
+ ): Promise<RequestWithdrawalResponse> {
200
+ validateUUID(walletId, 'walletId')
201
+ validateUUID(params.assetId, 'assetId')
202
+
203
+ if (!params.amount || params.amount.trim() === '') {
204
+ throw new Error('Invalid amount provided')
205
+ }
206
+
207
+ if (!params.recipientAddress || params.recipientAddress.trim() === '') {
208
+ throw new Error('Invalid recipient address provided')
209
+ }
210
+
211
+ if (params.recipientAddress.length > 256) {
212
+ throw new Error('Recipient address exceeds maximum length of 256 characters')
213
+ }
214
+
215
+ if (params.notes && params.notes.length > 500) {
216
+ throw new Error('Notes exceed maximum length of 500 characters')
217
+ }
218
+
219
+ this.log(`Requesting withdrawal from wallet ${walletId}`)
220
+ const response = await this.apiService.requestWithdrawal(walletId, params)
221
+ this.log(`Withdrawal request completed, auto_approved: ${response.auto_approved}`)
222
+
223
+ return response
224
+ }
225
+
226
+ /**
227
+ * Gets the webhook public key for a workspace
228
+ * @param workspaceId The workspace ID
229
+ * @returns Promise with webhook public key (base64 encoded ed25519 public key)
230
+ */
231
+ async getWebhookPublicKey(workspaceId: string): Promise<WebhookPublicKeyResponse> {
232
+ validateUUID(workspaceId, 'workspaceId')
233
+
234
+ this.log(`Getting webhook public key for workspace ${workspaceId}`)
235
+ const response = await this.apiService.getWebhookPublicKey(workspaceId)
236
+ return response
237
+ }
186
238
  }
package/src/signer.ts CHANGED
@@ -151,7 +151,7 @@ export class EtherSigner extends AbstractSigner {
151
151
  return result.status === TxStatus.Rejected
152
152
  }
153
153
  )
154
- console.log('reulst', result)
154
+ console.log('result', result)
155
155
 
156
156
  if (!result.hash) {
157
157
  throw new TransactionError(
@@ -165,7 +165,10 @@ export class EtherSigner extends AbstractSigner {
165
165
  }
166
166
 
167
167
  // Copied and editted from ethers.js -> Wallet -> BaseWallet
168
- async signTransaction(tx: TransactionRequest): Promise<string> {
168
+ async signTransaction(
169
+ tx: TransactionRequest,
170
+ options?: { idempotencyKey?: string }
171
+ ): Promise<string> {
169
172
  const startTime = new Date()
170
173
  console.log(`[WalletSDK] Transaction started at: ${startTime.toLocaleString()}`)
171
174
 
@@ -216,7 +219,11 @@ export class EtherSigner extends AbstractSigner {
216
219
  accessList: btx.accessList
217
220
  }
218
221
  // return unseralized as API signTransaction is an asynchoronous action
219
- const response = await this.APIService.signTransaction(this.walletDetail.WalletID, data)
222
+ const response = await this.APIService.signTransaction(
223
+ this.walletDetail.WalletID,
224
+ data,
225
+ options
226
+ )
220
227
  const txHash = await this.waitForTransactonStatus(response.transaction_id)
221
228
 
222
229
  const endTime = new Date()
@@ -230,7 +237,10 @@ export class EtherSigner extends AbstractSigner {
230
237
  return txHash
231
238
  }
232
239
 
233
- async sendTransaction(tx: TransactionRequest): Promise<TransactionResponse> {
240
+ async sendTransaction(
241
+ tx: TransactionRequest,
242
+ options?: { idempotencyKey?: string }
243
+ ): Promise<TransactionResponse> {
234
244
  const startTime = new Date()
235
245
  console.log(`[WalletSDK] sendTransaction started at: ${startTime.toLocaleString()}`)
236
246
 
@@ -272,7 +282,7 @@ export class EtherSigner extends AbstractSigner {
272
282
 
273
283
  console.log('[WalletSDK] Tx Data', txObj)
274
284
 
275
- const txHash = await this.signTransaction(txObj)
285
+ const txHash = await this.signTransaction(txObj, options)
276
286
 
277
287
  // Instead of creating a mock response, get the actual transaction from the provider
278
288
  const endTime = new Date()
@@ -341,7 +351,10 @@ export class EtherSigner extends AbstractSigner {
341
351
  return new TransactionResponse(txResponse, this.provider as Provider)
342
352
  }
343
353
 
344
- async signMessage(message: string | Uint8Array): Promise<string> {
354
+ async signMessage(
355
+ message: string | Uint8Array,
356
+ options?: { idempotencyKey?: string }
357
+ ): Promise<string> {
345
358
  if (!this.provider) {
346
359
  throw new Error('Provider is required for signing operations')
347
360
  }
@@ -357,11 +370,15 @@ export class EtherSigner extends AbstractSigner {
357
370
  const chainId = await this.getChainId()
358
371
  const messageStr = typeof message === 'string' ? message : Buffer.from(message).toString('hex')
359
372
 
360
- const response = await this.APIService.requestSign(this.walletDetail.WalletID, {
361
- method: 'eth_sign',
362
- message: messageStr,
363
- chain_id: chainId
364
- })
373
+ const response = await this.APIService.requestSign(
374
+ this.walletDetail.WalletID,
375
+ {
376
+ method: 'eth_sign',
377
+ message: messageStr,
378
+ chain_id: chainId
379
+ },
380
+ options
381
+ )
365
382
 
366
383
  return this.waitForSignature(this.walletDetail.WalletID, response.transaction_id)
367
384
  }
@@ -369,7 +386,8 @@ export class EtherSigner extends AbstractSigner {
369
386
  async signTypedData(
370
387
  domain: TypedDataDomain,
371
388
  types: Record<string, Array<TypedDataField>>,
372
- value: Record<string, any>
389
+ value: Record<string, any>,
390
+ options?: { idempotencyKey?: string }
373
391
  ): Promise<string> {
374
392
  if (!this.provider) {
375
393
  throw new Error('Provider is required for signing operations')
@@ -390,12 +408,16 @@ export class EtherSigner extends AbstractSigner {
390
408
  message: value
391
409
  })
392
410
 
393
- const response = await this.APIService.requestSign(this.walletDetail.WalletID, {
394
- method: 'eth_signTypedData_v4',
395
- message: '',
396
- chain_id: chainId,
397
- typed_data: typedData
398
- })
411
+ const response = await this.APIService.requestSign(
412
+ this.walletDetail.WalletID,
413
+ {
414
+ method: 'eth_signTypedData_v4',
415
+ message: '',
416
+ chain_id: chainId,
417
+ typed_data: typedData
418
+ },
419
+ options
420
+ )
399
421
 
400
422
  return this.waitForSignature(this.walletDetail.WalletID, response.transaction_id)
401
423
  }
@@ -117,7 +117,10 @@ export class SolanaSigner {
117
117
  * @param transaction Base64 encoded serialized transaction
118
118
  * @returns Signature as a base58 encoded string
119
119
  */
120
- async signTransaction(transaction: string): Promise<string> {
120
+ async signTransaction(
121
+ transaction: string,
122
+ options?: { idempotencyKey?: string }
123
+ ): Promise<string> {
121
124
  if (!this.address) {
122
125
  await this.getAddress()
123
126
  }
@@ -128,13 +131,17 @@ export class SolanaSigner {
128
131
  }
129
132
 
130
133
  // Call the signRaw API similar to EtherSigner
131
- const response = await this.APIService.signTransaction(this.walletDetail.WalletID, {
132
- ...data,
133
- meta: {
134
- tx_method: 'solana_signTransaction'
134
+ const response = await this.APIService.signTransaction(
135
+ this.walletDetail.WalletID,
136
+ {
137
+ ...data,
138
+ meta: {
139
+ tx_method: 'solana_signTransaction'
140
+ },
141
+ chainId: '1399811149'
135
142
  },
136
- chainId: '1399811149'
137
- })
143
+ options
144
+ )
138
145
 
139
146
  // Wait for the signature
140
147
  return this.waitForTransactionStatus(response.transaction_id)
@@ -145,7 +152,10 @@ export class SolanaSigner {
145
152
  * @param message The message to sign (string or Uint8Array)
146
153
  * @returns Signature as a base58 encoded string
147
154
  */
148
- async signMessage(message: string | Uint8Array): Promise<string> {
155
+ async signMessage(
156
+ message: string | Uint8Array,
157
+ options?: { idempotencyKey?: string }
158
+ ): Promise<string> {
149
159
  if (!this.address) {
150
160
  await this.getAddress()
151
161
  }
@@ -153,11 +163,15 @@ export class SolanaSigner {
153
163
  const messageStr =
154
164
  typeof message === 'string' ? message : Buffer.from(message).toString('base64')
155
165
 
156
- const response = await this.APIService.requestSign(this.walletDetail.WalletID, {
157
- method: 'solana_signMessage',
158
- message: messageStr,
159
- chain_id: 0 // Not used for Solana but required by API
160
- })
166
+ const response = await this.APIService.requestSign(
167
+ this.walletDetail.WalletID,
168
+ {
169
+ method: 'solana_signMessage',
170
+ message: messageStr,
171
+ chain_id: 0 // Not used for Solana but required by API
172
+ },
173
+ options
174
+ )
161
175
 
162
176
  return this.waitForTransactionStatus(response.transaction_id)
163
177
  }
@@ -167,7 +181,10 @@ export class SolanaSigner {
167
181
  * @param transaction Base64 encoded serialized transaction
168
182
  * @returns Transaction signature
169
183
  */
170
- async signAndSendTransaction(transaction: string): Promise<string> {
184
+ async signAndSendTransaction(
185
+ transaction: string,
186
+ options?: { idempotencyKey?: string }
187
+ ): Promise<string> {
171
188
  if (!this.address) {
172
189
  await this.getAddress()
173
190
  }
@@ -178,7 +195,11 @@ export class SolanaSigner {
178
195
  method: 'solana_signAndSendTransaction'
179
196
  }
180
197
 
181
- const response = await this.APIService.signTransaction(this.walletDetail.WalletID, data)
198
+ const response = await this.APIService.signTransaction(
199
+ this.walletDetail.WalletID,
200
+ data,
201
+ options
202
+ )
182
203
  const txHash = await this.waitForTransactionStatus(response.transaction_id)
183
204
  console.log('transaction succeed!')
184
205
 
@@ -190,7 +211,10 @@ export class SolanaSigner {
190
211
  * @param transactions Array of base64 encoded serialized transactions
191
212
  * @returns Array of signatures as base58 encoded strings
192
213
  */
193
- async signAllTransactions(transactions: string[]): Promise<{ transactions: string[] }> {
214
+ async signAllTransactions(
215
+ transactions: string[],
216
+ options?: { idempotencyKey?: string }
217
+ ): Promise<{ transactions: string[] }> {
194
218
  if (!this.address) {
195
219
  await this.getAddress()
196
220
  }
@@ -198,7 +222,7 @@ export class SolanaSigner {
198
222
  // We need to get the signatures and then incorporate them into the transactions
199
223
  const signaturePromises = transactions.map(async (transaction) => {
200
224
  // Get the signature
201
- const signature = await this.signTransaction(transaction)
225
+ const signature = await this.signTransaction(transaction, options)
202
226
 
203
227
  // Here you would need to incorporate the signature into the transaction
204
228
  // This is a placeholder - you'll need to implement actual signature incorporation