@fystack/sdk 0.1.1 → 0.1.3
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 +121 -57
- package/dist/index.d.cts +318 -267
- package/dist/index.d.mts +318 -267
- package/dist/index.esm.d.ts +318 -267
- package/dist/index.esm.js +121 -58
- package/dist/index.mjs +121 -58
- package/dist/types/index.d.ts +318 -267
- package/package.json +1 -1
- package/readme.md +7 -1
- package/src/api.ts +49 -14
- package/src/config.ts +4 -2
- package/src/enum.ts +46 -0
- package/src/index.ts +1 -0
- package/src/sdk.ts +31 -7
- package/src/signer.ts +9 -4
- package/src/solanaSigner.ts +11 -4
- package/src/types.ts +14 -30
- package/test.js +0 -76
package/src/api.ts
CHANGED
|
@@ -10,10 +10,9 @@ import {
|
|
|
10
10
|
TransactionStatusResponse,
|
|
11
11
|
CreateWalletResponse,
|
|
12
12
|
WalletCreationStatusResponse,
|
|
13
|
-
WalletType,
|
|
14
13
|
WalletAsset,
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
DepositAddressResponse,
|
|
15
|
+
RescanTransactionParams
|
|
17
16
|
} from './types'
|
|
18
17
|
import {
|
|
19
18
|
CreateCheckoutPayload,
|
|
@@ -23,6 +22,7 @@ import {
|
|
|
23
22
|
GetCheckoutPaymentResponse,
|
|
24
23
|
GetCheckoutResponse
|
|
25
24
|
} from './payment'
|
|
25
|
+
import { AddressType, DestinationType, WalletPurpose, WalletType } from './enum'
|
|
26
26
|
|
|
27
27
|
interface APIResponse {
|
|
28
28
|
data: any
|
|
@@ -45,9 +45,18 @@ export interface WalletDetail {
|
|
|
45
45
|
Address: string
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
export interface SweepTaskParams {
|
|
49
|
+
minTriggerValueUsd: number
|
|
50
|
+
destinationWalletId: string
|
|
51
|
+
destinationType: DestinationType
|
|
52
|
+
}
|
|
53
|
+
|
|
48
54
|
export interface CreateWalletPayload {
|
|
49
55
|
name: string
|
|
50
56
|
walletType: WalletType
|
|
57
|
+
walletPurpose?: WalletPurpose
|
|
58
|
+
sweepTaskParams?: SweepTaskParams
|
|
59
|
+
sweepTaskId?: string
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
export interface PaymentServiceParams {
|
|
@@ -55,11 +64,6 @@ export interface PaymentServiceParams {
|
|
|
55
64
|
environment: Environment
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
export enum WalletAddressType {
|
|
59
|
-
Evm = 'evm',
|
|
60
|
-
Sol = 'sol'
|
|
61
|
-
}
|
|
62
|
-
|
|
63
67
|
async function composeAPIHeaders(
|
|
64
68
|
credentials: APICredentials,
|
|
65
69
|
httpMethod: string,
|
|
@@ -67,7 +71,13 @@ async function composeAPIHeaders(
|
|
|
67
71
|
body: Record<string, any> = {}
|
|
68
72
|
): Promise<Record<string, string>> {
|
|
69
73
|
if (credentials.apiSecret == '') {
|
|
70
|
-
// If APISecret is not provided,
|
|
74
|
+
// If APISecret is not provided, use authToken
|
|
75
|
+
if (credentials.authToken) {
|
|
76
|
+
return {
|
|
77
|
+
Authorization: credentials.authToken
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// fallback to cookie mode with no headers
|
|
71
81
|
return {}
|
|
72
82
|
}
|
|
73
83
|
|
|
@@ -103,10 +113,7 @@ export class APIService {
|
|
|
103
113
|
this.API = createAPI(environment)
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
async getWalletDetail(
|
|
107
|
-
addressType: WalletAddressType = WalletAddressType.Evm,
|
|
108
|
-
walletId?: string
|
|
109
|
-
): Promise<WalletDetail> {
|
|
116
|
+
async getWalletDetail(addressType = AddressType.Evm, walletId?: string): Promise<WalletDetail> {
|
|
110
117
|
const endpoint = this.API.endpoints.getWalletDetail(walletId)
|
|
111
118
|
const headers = await composeAPIHeaders(this.credentials, 'GET', endpoint)
|
|
112
119
|
console.info('headers', headers)
|
|
@@ -195,6 +202,18 @@ export class APIService {
|
|
|
195
202
|
const response = await get(endpoint, headers)
|
|
196
203
|
return response.data
|
|
197
204
|
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Rescans a transaction on a specific network
|
|
208
|
+
* @param params Transaction hash and network ID
|
|
209
|
+
* @returns API response
|
|
210
|
+
*/
|
|
211
|
+
async rescanTransaction(params: RescanTransactionParams): Promise<void> {
|
|
212
|
+
const endpoint = this.API.endpoints.rescanTransaction()
|
|
213
|
+
const transformedParams = transformRescanTransactionParams(params)
|
|
214
|
+
const headers = await composeAPIHeaders(this.credentials, 'POST', endpoint, transformedParams)
|
|
215
|
+
await post(endpoint, transformedParams, headers)
|
|
216
|
+
}
|
|
198
217
|
}
|
|
199
218
|
|
|
200
219
|
export class PaymentService {
|
|
@@ -323,7 +342,23 @@ export function transformWalletDetail(data: Record<string, string>): WalletDetai
|
|
|
323
342
|
export function transformCreateWalletPayload(data: CreateWalletPayload) {
|
|
324
343
|
return {
|
|
325
344
|
name: data.name,
|
|
326
|
-
wallet_type: data.walletType
|
|
345
|
+
wallet_type: data.walletType,
|
|
346
|
+
...(data.walletPurpose !== undefined && { wallet_purpose: data.walletPurpose }),
|
|
347
|
+
...(data.sweepTaskParams !== undefined && {
|
|
348
|
+
sweep_task_params: {
|
|
349
|
+
min_trigger_value_usd: data.sweepTaskParams?.minTriggerValueUsd,
|
|
350
|
+
destination_wallet_id: data.sweepTaskParams?.destinationWalletId,
|
|
351
|
+
destination_type: data.sweepTaskParams?.destinationType
|
|
352
|
+
}
|
|
353
|
+
}),
|
|
354
|
+
...(data.sweepTaskId !== undefined && { sweep_task_id: data.sweepTaskId })
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export function transformRescanTransactionParams(data: RescanTransactionParams) {
|
|
359
|
+
return {
|
|
360
|
+
tx_hash: data.txHash,
|
|
361
|
+
network_id: data.networkId
|
|
327
362
|
}
|
|
328
363
|
}
|
|
329
364
|
|
package/src/config.ts
CHANGED
|
@@ -19,6 +19,7 @@ export interface APIEndpoints {
|
|
|
19
19
|
getWalletCreationStatus: (walletId: string) => string
|
|
20
20
|
getWalletAssets: (walletId: string) => string
|
|
21
21
|
getDepositAddress: (walletId: string, addressType: string) => string
|
|
22
|
+
rescanTransaction: () => string
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const getBaseURL = (env: Environment): string => {
|
|
@@ -26,7 +27,7 @@ const getBaseURL = (env: Environment): string => {
|
|
|
26
27
|
case Environment.Local:
|
|
27
28
|
return 'http://localhost:8150'
|
|
28
29
|
case Environment.Sandbox:
|
|
29
|
-
return 'https://
|
|
30
|
+
return 'https://api-dev.fystack.io'
|
|
30
31
|
case Environment.Production:
|
|
31
32
|
return 'https://api.fystack.io'
|
|
32
33
|
}
|
|
@@ -67,7 +68,8 @@ const createAPI = (env: Environment): APIConfig => {
|
|
|
67
68
|
withBaseURL(`/wallets/creation-status/${walletId}`),
|
|
68
69
|
getWalletAssets: (walletId: string) => withBaseURL(`/wallets/${walletId}/assets`),
|
|
69
70
|
getDepositAddress: (walletId: string, addressType: string) =>
|
|
70
|
-
withBaseURL(`/wallets/${walletId}/deposit-address?address_type=${addressType}`)
|
|
71
|
+
withBaseURL(`/wallets/${walletId}/deposit-address?address_type=${addressType}`),
|
|
72
|
+
rescanTransaction: () => withBaseURL('/networks/rescan-transaction')
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
}
|
package/src/enum.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Wallets
|
|
2
|
+
export enum WalletType {
|
|
3
|
+
Standard = 'standard',
|
|
4
|
+
MPC = 'mpc'
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export enum WalletPurpose {
|
|
8
|
+
General = 'general',
|
|
9
|
+
Gastank = 'gas_tank',
|
|
10
|
+
Deployment = 'deployment',
|
|
11
|
+
Custody = 'custody',
|
|
12
|
+
User = 'user',
|
|
13
|
+
Payment = 'payment'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export enum WalletCreationStatus {
|
|
17
|
+
Pending = 'pending',
|
|
18
|
+
Success = 'success',
|
|
19
|
+
Error = 'error'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export enum AddressType {
|
|
23
|
+
Evm = 'evm',
|
|
24
|
+
Solana = 'sol',
|
|
25
|
+
Tron = 'tron'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export enum DestinationType {
|
|
29
|
+
InternalWallet = 'internal_wallet',
|
|
30
|
+
AddressBook = 'address_book'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export enum TxStatus {
|
|
34
|
+
Pending = 'pending',
|
|
35
|
+
Completed = 'completed',
|
|
36
|
+
Confirmed = 'confirmed',
|
|
37
|
+
Failed = 'failed',
|
|
38
|
+
PendingApproval = 'pending_approval',
|
|
39
|
+
Rejected = 'rejected'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export enum TxApprovalStatus {
|
|
43
|
+
Pending = 'pending',
|
|
44
|
+
Approved = 'approved',
|
|
45
|
+
Rejected = 'rejected'
|
|
46
|
+
}
|
package/src/index.ts
CHANGED
package/src/sdk.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { APIService } from './api'
|
|
2
|
-
import { APICredentials, CreateWalletOptions } from './types'
|
|
3
2
|
import { Environment } from './config'
|
|
4
3
|
import { StatusPoller } from './utils/statusPoller'
|
|
5
4
|
import {
|
|
6
|
-
WalletCreationStatus,
|
|
7
5
|
CreateWalletResponse,
|
|
8
6
|
WalletCreationStatusResponse,
|
|
9
|
-
WalletType,
|
|
10
7
|
WalletAsset,
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
DepositAddressResponse,
|
|
9
|
+
APICredentials,
|
|
10
|
+
CreateWalletOptions,
|
|
11
|
+
RescanTransactionParams
|
|
13
12
|
} from './types'
|
|
14
13
|
import { validateUUID } from './utils'
|
|
14
|
+
import { AddressType, WalletCreationStatus, WalletType } from './enum'
|
|
15
15
|
|
|
16
16
|
export interface SDKOptions {
|
|
17
17
|
credentials: APICredentials
|
|
@@ -45,11 +45,20 @@ export class FystackSDK {
|
|
|
45
45
|
options: CreateWalletOptions,
|
|
46
46
|
waitForCompletion: boolean = true
|
|
47
47
|
): Promise<CreateWalletResponse> {
|
|
48
|
-
const {
|
|
48
|
+
const {
|
|
49
|
+
name,
|
|
50
|
+
walletType = WalletType.Standard,
|
|
51
|
+
sweepTaskParams,
|
|
52
|
+
walletPurpose,
|
|
53
|
+
sweepTaskId
|
|
54
|
+
} = options
|
|
49
55
|
|
|
50
56
|
const response = await this.apiService.createWallet({
|
|
51
57
|
name,
|
|
52
|
-
walletType
|
|
58
|
+
walletType,
|
|
59
|
+
walletPurpose,
|
|
60
|
+
sweepTaskParams,
|
|
61
|
+
sweepTaskId
|
|
53
62
|
})
|
|
54
63
|
|
|
55
64
|
if (waitForCompletion && response.status === WalletCreationStatus.Pending) {
|
|
@@ -137,4 +146,19 @@ export class FystackSDK {
|
|
|
137
146
|
const depositAddressInfo = await this.apiService.getDepositAddress(walletId, addressType)
|
|
138
147
|
return depositAddressInfo
|
|
139
148
|
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Rescans a transaction on a specific network
|
|
152
|
+
* @param params Transaction hash and network ID
|
|
153
|
+
* @returns Promise that resolves when the rescan is initiated
|
|
154
|
+
*/
|
|
155
|
+
async rescanTransaction(params: RescanTransactionParams): Promise<void> {
|
|
156
|
+
validateUUID(params.networkId, 'networkId')
|
|
157
|
+
|
|
158
|
+
if (!params.txHash || params.txHash.trim() === '') {
|
|
159
|
+
throw new Error('Invalid transaction hash provided')
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await this.apiService.rescanTransaction(params)
|
|
163
|
+
}
|
|
140
164
|
}
|
package/src/signer.ts
CHANGED
|
@@ -15,10 +15,11 @@ import {
|
|
|
15
15
|
Signature
|
|
16
16
|
} from 'ethers'
|
|
17
17
|
import { TransactionRequest } from 'ethers/src.ts/providers'
|
|
18
|
-
import { APIService, WalletDetail
|
|
19
|
-
import { APICredentials, TransactionStatusResponse,
|
|
18
|
+
import { APIService, WalletDetail } from './api'
|
|
19
|
+
import { APICredentials, TransactionStatusResponse, TransactionError } from './types'
|
|
20
20
|
import { Environment } from './config'
|
|
21
21
|
import { StatusPoller, StatusPollerOptions } from './utils/statusPoller'
|
|
22
|
+
import { AddressType, TxStatus } from './enum'
|
|
22
23
|
|
|
23
24
|
export class EtherSigner extends AbstractSigner {
|
|
24
25
|
private address!: string
|
|
@@ -64,12 +65,16 @@ export class EtherSigner extends AbstractSigner {
|
|
|
64
65
|
return this.address
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
if (
|
|
68
|
+
if (
|
|
69
|
+
!this.APICredentials.apiKey &&
|
|
70
|
+
!this.APICredentials.authToken &&
|
|
71
|
+
!this.walletDetail.WalletID
|
|
72
|
+
) {
|
|
68
73
|
throw new Error('Wallet detail not found, use setWallet(walletId) to set wallet first!')
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
const detail: WalletDetail = await this.APIService.getWalletDetail(
|
|
72
|
-
|
|
77
|
+
AddressType.Evm,
|
|
73
78
|
this.walletDetail?.WalletID
|
|
74
79
|
)
|
|
75
80
|
|
package/src/solanaSigner.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { APIService,
|
|
2
|
-
import { APICredentials, TransactionStatusResponse,
|
|
1
|
+
import { APIService, WalletDetail } from './api'
|
|
2
|
+
import { APICredentials, TransactionStatusResponse, TransactionError } from './types'
|
|
3
3
|
import { Environment } from './config'
|
|
4
4
|
import { StatusPoller, StatusPollerOptions } from './utils/statusPoller'
|
|
5
5
|
import { Transaction, PublicKey, VersionedTransaction } from '@solana/web3.js'
|
|
6
6
|
import bs58 from 'bs58'
|
|
7
7
|
import { Buffer } from 'buffer'
|
|
8
|
+
import { AddressType, TxStatus } from './enum'
|
|
8
9
|
|
|
9
10
|
export class SolanaSigner {
|
|
10
11
|
private address!: string
|
|
@@ -12,12 +13,14 @@ export class SolanaSigner {
|
|
|
12
13
|
private APIKey: string
|
|
13
14
|
private walletDetail: WalletDetail
|
|
14
15
|
private pollerOptions?: StatusPollerOptions
|
|
16
|
+
private APICredentials!: APICredentials
|
|
15
17
|
|
|
16
18
|
constructor(
|
|
17
19
|
credentials: APICredentials,
|
|
18
20
|
environment: Environment,
|
|
19
21
|
pollerOptions?: StatusPollerOptions
|
|
20
22
|
) {
|
|
23
|
+
this.APICredentials = credentials
|
|
21
24
|
this.APIKey = credentials.apiKey
|
|
22
25
|
this.APIService = new APIService(credentials, environment)
|
|
23
26
|
this.pollerOptions = pollerOptions
|
|
@@ -45,12 +48,16 @@ export class SolanaSigner {
|
|
|
45
48
|
return this.address
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
if (
|
|
51
|
+
if (
|
|
52
|
+
!this.APICredentials.apiKey &&
|
|
53
|
+
!this.APICredentials.apiSecret &&
|
|
54
|
+
!this.walletDetail?.WalletID
|
|
55
|
+
) {
|
|
49
56
|
throw new Error('Wallet detail not found, use setWallet(walletId) to set wallet first!')
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
const detail: WalletDetail = await this.APIService.getWalletDetail(
|
|
53
|
-
|
|
60
|
+
AddressType.Solana,
|
|
54
61
|
this.walletDetail?.WalletID
|
|
55
62
|
)
|
|
56
63
|
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { SweepTaskParams } from './api'
|
|
2
|
+
import { TxApprovalStatus, TxStatus, WalletCreationStatus, WalletPurpose, WalletType } from './enum'
|
|
3
|
+
|
|
1
4
|
export class TransactionError extends Error {
|
|
2
5
|
constructor(
|
|
3
6
|
message: string,
|
|
@@ -9,24 +12,13 @@ export class TransactionError extends Error {
|
|
|
9
12
|
this.name = 'TransactionError'
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
|
-
export enum TxStatus {
|
|
13
|
-
Pending = 'pending',
|
|
14
|
-
Completed = 'completed',
|
|
15
|
-
Confirmed = 'confirmed',
|
|
16
|
-
Failed = 'failed',
|
|
17
|
-
PendingApproval = 'pending_approval',
|
|
18
|
-
Rejected = 'rejected'
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export enum TxApprovalStatus {
|
|
22
|
-
Pending = 'pending',
|
|
23
|
-
Approved = 'approved',
|
|
24
|
-
Rejected = 'rejected'
|
|
25
|
-
}
|
|
26
15
|
|
|
27
16
|
export interface APICredentials {
|
|
28
17
|
apiKey: string
|
|
29
18
|
apiSecret: string
|
|
19
|
+
|
|
20
|
+
// Optional
|
|
21
|
+
authToken?: string
|
|
30
22
|
}
|
|
31
23
|
|
|
32
24
|
export interface WebhookEvent {
|
|
@@ -76,20 +68,12 @@ export interface TransactionStatusResponse {
|
|
|
76
68
|
failed_reason?: string
|
|
77
69
|
}
|
|
78
70
|
|
|
79
|
-
// Wallets
|
|
80
|
-
export enum WalletType {
|
|
81
|
-
Standard = 'standard',
|
|
82
|
-
MPC = 'mpc'
|
|
83
|
-
}
|
|
84
|
-
|
|
85
71
|
export interface CreateWalletOptions {
|
|
86
72
|
name: string
|
|
87
73
|
walletType: WalletType
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
Success = 'success',
|
|
92
|
-
Error = 'error'
|
|
74
|
+
walletPurpose?: WalletPurpose
|
|
75
|
+
sweepTaskParams?: SweepTaskParams
|
|
76
|
+
sweepTaskId?: string
|
|
93
77
|
}
|
|
94
78
|
|
|
95
79
|
export interface CreateWalletResponse {
|
|
@@ -149,13 +133,13 @@ export interface WalletAsset {
|
|
|
149
133
|
asset: WalletAssetDetail
|
|
150
134
|
}
|
|
151
135
|
|
|
152
|
-
export enum AddressType {
|
|
153
|
-
Evm = 'evm',
|
|
154
|
-
Solana = 'sol'
|
|
155
|
-
}
|
|
156
|
-
|
|
157
136
|
export interface DepositAddressResponse {
|
|
158
137
|
asset_id?: string
|
|
159
138
|
address: string
|
|
160
139
|
qr_code: string
|
|
161
140
|
}
|
|
141
|
+
|
|
142
|
+
export interface RescanTransactionParams {
|
|
143
|
+
txHash: string
|
|
144
|
+
networkId: string
|
|
145
|
+
}
|
package/test.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { TypedDataEncoder, verifyTypedData, Signature } from 'ethers'
|
|
2
|
-
|
|
3
|
-
// 0x2f71f2595162eaca40708bf6d6327d437e760b27d26f3a933389ebdb4eedf3b167008df6f1d403503c82a6d58da5659b14c578019603d6b138b2c03729c92af701
|
|
4
|
-
// 0xd77d10c530b25d1ea6a466eb2b3169138b5ca0d1320ff54bbad000d97f686d0a314c5233844d84da5adf3580afa38c82d9595c22a985acfea02ca722c55df48a00
|
|
5
|
-
// Example usage
|
|
6
|
-
const address = '0xFFe120Fd4D5AB5A9f25b25c30620ac8ee3E1EF21'
|
|
7
|
-
const jsonData = {
|
|
8
|
-
domain: {
|
|
9
|
-
name: 'Permit2',
|
|
10
|
-
chainId: '8453',
|
|
11
|
-
verifyingContract: '0x000000000022d473030f116ddee9f6b43ac78ba3'
|
|
12
|
-
},
|
|
13
|
-
types: {
|
|
14
|
-
PermitSingle: [
|
|
15
|
-
{ name: 'details', type: 'PermitDetails' },
|
|
16
|
-
{ name: 'spender', type: 'address' },
|
|
17
|
-
{ name: 'sigDeadline', type: 'uint256' }
|
|
18
|
-
],
|
|
19
|
-
PermitDetails: [
|
|
20
|
-
{ name: 'token', type: 'address' },
|
|
21
|
-
{ name: 'amount', type: 'uint160' },
|
|
22
|
-
{ name: 'expiration', type: 'uint48' },
|
|
23
|
-
{ name: 'nonce', type: 'uint48' }
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
message: {
|
|
27
|
-
details: {
|
|
28
|
-
token: '0x0b3e328455c4059eeb9e3f84b5543f74e24e7e1b',
|
|
29
|
-
amount: '1461501637330902918203684832716283019655932542975',
|
|
30
|
-
expiration: '1743496074',
|
|
31
|
-
nonce: '0'
|
|
32
|
-
},
|
|
33
|
-
spender: '0x6ff5693b99212da76ad316178a184ab56d299b43',
|
|
34
|
-
sigDeadline: '1740905874'
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const signature =
|
|
38
|
-
'0x032f29648f9c2d9d2524aef755c225b96121f2c9b01beee5869a70ef95eb089548dc41f71126dac83c1632738dbea12bf5c925715068e32dda0064701bfc019e00'
|
|
39
|
-
|
|
40
|
-
async function verifySignature(address, jsonData, signature) {
|
|
41
|
-
try {
|
|
42
|
-
// Step 1: Compute the EIP-712 hash
|
|
43
|
-
const computedHash = TypedDataEncoder.hash(jsonData.domain, jsonData.types, jsonData.message)
|
|
44
|
-
console.log('🔹 Computed EIP-712 Hash:', computedHash)
|
|
45
|
-
|
|
46
|
-
// Step 2: Recover the signer address
|
|
47
|
-
const recoveredAddress = verifyTypedData(
|
|
48
|
-
jsonData.domain,
|
|
49
|
-
jsonData.types,
|
|
50
|
-
jsonData.message,
|
|
51
|
-
signature
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
console.log('✅ Recovered Address:', recoveredAddress)
|
|
55
|
-
console.log('🔹 Expected Address:', address)
|
|
56
|
-
|
|
57
|
-
// Step 3: Compare the addresses
|
|
58
|
-
const isValid = recoveredAddress.toLowerCase() === address.toLowerCase()
|
|
59
|
-
console.log('🔹 Is Signature Valid?', isValid)
|
|
60
|
-
|
|
61
|
-
// Step 4: Debug signature parts (r, s, v)
|
|
62
|
-
const sig = Signature.from(signature)
|
|
63
|
-
console.log('🔹 Signature Parts:')
|
|
64
|
-
console.log(' r:', sig.r)
|
|
65
|
-
console.log(' s:', sig.s)
|
|
66
|
-
console.log(' v:', sig.v)
|
|
67
|
-
|
|
68
|
-
return isValid
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error('❌ Signature Verification Failed:', error)
|
|
71
|
-
return false
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Run verification
|
|
76
|
-
verifySignature(address, jsonData, signature)
|