@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.
- package/dist/index.cjs +110 -26
- package/dist/index.d.cts +122 -11
- package/dist/index.d.mts +122 -11
- package/dist/index.esm.d.ts +122 -11
- package/dist/index.esm.js +110 -27
- package/dist/index.mjs +110 -27
- package/dist/types/index.d.ts +122 -11
- package/package.json +1 -1
- package/src/api.ts +61 -9
- package/src/config.ts +5 -1
- package/src/enum.ts +10 -0
- package/src/sdk.ts +53 -1
- package/src/signer.ts +40 -18
- package/src/solanaSigner.ts +41 -17
- package/src/types.ts +67 -1
- package/test.js +76 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -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
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
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
|
|
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
|
|
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
|
|
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[]
|
|
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
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
|
|
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
|
|
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(
|
|
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(
|
|
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('
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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
|
}
|
package/src/solanaSigner.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|