payment-kit 1.25.2 → 1.25.5
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/api/src/libs/payment.ts
CHANGED
|
@@ -253,6 +253,15 @@ export async function isDelegationSufficientForPayment(args: {
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
// Log delegation check context for debugging
|
|
257
|
+
logger.info('isDelegationSufficientForPayment: checking delegation', {
|
|
258
|
+
originalUserDid: userDid,
|
|
259
|
+
resolvedDelegator: delegator,
|
|
260
|
+
delegatorChanged: userDid !== delegator,
|
|
261
|
+
walletAddress: wallet.address,
|
|
262
|
+
paymentMethodApiHost: paymentMethod.settings?.arcblock?.api_host,
|
|
263
|
+
});
|
|
264
|
+
|
|
256
265
|
const client = paymentMethod.getOcapClient();
|
|
257
266
|
|
|
258
267
|
// have delegated before? Use migration-aware fallback query
|
|
@@ -263,6 +272,12 @@ export async function isDelegationSufficientForPayment(args: {
|
|
|
263
272
|
client,
|
|
264
273
|
});
|
|
265
274
|
if (!delegationResult) {
|
|
275
|
+
logger.error('isDelegationSufficientForPayment: no delegation address found', {
|
|
276
|
+
delegator,
|
|
277
|
+
storedDelegationAddress,
|
|
278
|
+
subscriptionDelegationAddress: subscription?.payment_details?.arcblock?.delegation_address,
|
|
279
|
+
subscriptionId: subscription?.id,
|
|
280
|
+
});
|
|
266
281
|
return { sufficient: false, reason: 'NO_DELEGATION' };
|
|
267
282
|
}
|
|
268
283
|
|
|
@@ -15,17 +15,30 @@ import { wallet } from './auth';
|
|
|
15
15
|
import logger from './logger';
|
|
16
16
|
import { Subscription } from '../store/models';
|
|
17
17
|
|
|
18
|
-
// Cache for migratedFrom list (
|
|
18
|
+
// Cache for migratedFrom list (keyed by wallet.address + chain host)
|
|
19
19
|
let cachedMigratedFrom: string[] | null = null;
|
|
20
20
|
let cachedWalletAddress: string | null = null;
|
|
21
|
+
let cachedChainHost: string | null = null;
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Get the migratedFrom list for the current app wallet (with caching)
|
|
24
|
-
* The cache is invalidated when wallet.address changes
|
|
25
|
+
* The cache is invalidated when wallet.address or chain host changes
|
|
25
26
|
*/
|
|
26
27
|
export async function getMigratedFromList(client: OcapClient): Promise<string[]> {
|
|
27
|
-
//
|
|
28
|
-
|
|
28
|
+
// @ts-ignore - OcapClient has host property
|
|
29
|
+
const chainHost = client?.config?.httpEndpoint || 'unknown';
|
|
30
|
+
// If wallet address and chain host haven't changed, use cached value
|
|
31
|
+
if (
|
|
32
|
+
wallet.address === cachedWalletAddress &&
|
|
33
|
+
chainHost === cachedChainHost &&
|
|
34
|
+
cachedMigratedFrom &&
|
|
35
|
+
cachedMigratedFrom.length > 0
|
|
36
|
+
) {
|
|
37
|
+
logger.info('wallet-migration: using cached migratedFrom list', {
|
|
38
|
+
walletAddress: wallet.address,
|
|
39
|
+
chainHost,
|
|
40
|
+
migratedFromCount: cachedMigratedFrom.length,
|
|
41
|
+
});
|
|
29
42
|
return cachedMigratedFrom;
|
|
30
43
|
}
|
|
31
44
|
|
|
@@ -34,17 +47,23 @@ export async function getMigratedFromList(client: OcapClient): Promise<string[]>
|
|
|
34
47
|
const { state } = await client.getAccountState({ address: wallet.address });
|
|
35
48
|
cachedMigratedFrom = state?.migratedFrom || [];
|
|
36
49
|
cachedWalletAddress = wallet.address;
|
|
50
|
+
cachedChainHost = chainHost;
|
|
37
51
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
logger.info('wallet-migration: loaded migratedFrom list', {
|
|
53
|
+
walletAddress: wallet.address,
|
|
54
|
+
chainHost,
|
|
55
|
+
migratedFromCount: cachedMigratedFrom.length,
|
|
56
|
+
migratedFrom: cachedMigratedFrom,
|
|
57
|
+
migratedTo: state?.migratedTo,
|
|
58
|
+
});
|
|
44
59
|
|
|
45
60
|
return cachedMigratedFrom;
|
|
46
61
|
} catch (err) {
|
|
47
|
-
logger.error('wallet-migration: failed to get migratedFrom list', {
|
|
62
|
+
logger.error('wallet-migration: failed to get migratedFrom list', {
|
|
63
|
+
walletAddress: wallet.address,
|
|
64
|
+
chainHost,
|
|
65
|
+
error: err,
|
|
66
|
+
});
|
|
48
67
|
return [];
|
|
49
68
|
}
|
|
50
69
|
}
|
|
@@ -54,6 +73,7 @@ export async function getMigratedFromList(client: OcapClient): Promise<string[]>
|
|
|
54
73
|
*/
|
|
55
74
|
export function clearMigratedFromCache(): void {
|
|
56
75
|
cachedMigratedFrom = null;
|
|
76
|
+
cachedChainHost = null;
|
|
57
77
|
cachedWalletAddress = null;
|
|
58
78
|
}
|
|
59
79
|
|
|
@@ -85,19 +105,67 @@ export async function getDelegationAddressWithFallback({
|
|
|
85
105
|
delegator,
|
|
86
106
|
client,
|
|
87
107
|
}: GetDelegationAddressParams): Promise<AddressWithFallbackResult | null> {
|
|
88
|
-
//
|
|
108
|
+
// @ts-ignore - OcapClient has host property
|
|
109
|
+
const chainHost = client?.config?.httpEndpoint || 'unknown';
|
|
110
|
+
|
|
111
|
+
logger.info('wallet-migration: getDelegationAddressWithFallback called', {
|
|
112
|
+
delegator,
|
|
113
|
+
storedAddress: storedAddress || null,
|
|
114
|
+
walletAddress: wallet.address,
|
|
115
|
+
chainHost,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// 1. Check stored delegation_address first - but verify it has valid state
|
|
89
119
|
if (storedAddress) {
|
|
90
|
-
|
|
120
|
+
try {
|
|
121
|
+
const { state: storedState } = await client.getDelegateState({ address: storedAddress });
|
|
122
|
+
if (storedState?.ops?.length > 0) {
|
|
123
|
+
logger.info('wallet-migration: found valid delegation at stored address', {
|
|
124
|
+
storedAddress,
|
|
125
|
+
delegator,
|
|
126
|
+
opsCount: storedState.ops.length,
|
|
127
|
+
});
|
|
128
|
+
return { address: storedAddress, needsBackfill: false, source: 'stored' };
|
|
129
|
+
}
|
|
130
|
+
logger.warn('wallet-migration: stored delegation address has no valid state, falling back', {
|
|
131
|
+
storedAddress,
|
|
132
|
+
delegator,
|
|
133
|
+
hasState: !!storedState,
|
|
134
|
+
opsCount: storedState?.ops?.length || 0,
|
|
135
|
+
});
|
|
136
|
+
} catch (err) {
|
|
137
|
+
logger.warn('wallet-migration: failed to query stored delegation address, falling back', {
|
|
138
|
+
storedAddress,
|
|
139
|
+
delegator,
|
|
140
|
+
error: err,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// Continue to fallback instead of returning early
|
|
91
144
|
}
|
|
92
145
|
|
|
93
146
|
// 2. Try current wallet.address
|
|
94
147
|
const currentAddress = toDelegateAddress(delegator, wallet.address);
|
|
148
|
+
let currentStateResult: { hasState: boolean; opsCount: number; error?: string } = {
|
|
149
|
+
hasState: false,
|
|
150
|
+
opsCount: 0,
|
|
151
|
+
};
|
|
95
152
|
try {
|
|
96
153
|
const { state: currentState } = await client.getDelegateState({ address: currentAddress });
|
|
154
|
+
currentStateResult = {
|
|
155
|
+
hasState: !!currentState,
|
|
156
|
+
opsCount: currentState?.ops?.length || 0,
|
|
157
|
+
};
|
|
97
158
|
if (currentState?.ops?.length > 0) {
|
|
159
|
+
logger.info('wallet-migration: found valid delegation at current address', {
|
|
160
|
+
currentAddress,
|
|
161
|
+
delegator,
|
|
162
|
+
walletAddress: wallet.address,
|
|
163
|
+
opsCount: currentState.ops.length,
|
|
164
|
+
});
|
|
98
165
|
return { address: currentAddress, needsBackfill: true, source: 'current' };
|
|
99
166
|
}
|
|
100
167
|
} catch (err) {
|
|
168
|
+
currentStateResult.error = String(err);
|
|
101
169
|
logger.warn('wallet-migration: failed to query current delegation state', {
|
|
102
170
|
address: currentAddress,
|
|
103
171
|
error: err,
|
|
@@ -106,11 +174,24 @@ export async function getDelegationAddressWithFallback({
|
|
|
106
174
|
|
|
107
175
|
// 3. Fallback to migratedFrom addresses
|
|
108
176
|
const migratedFrom = await getMigratedFromList(client);
|
|
177
|
+
const migratedResults: Array<{
|
|
178
|
+
appDid: string;
|
|
179
|
+
address: string;
|
|
180
|
+
hasState: boolean;
|
|
181
|
+
opsCount: number;
|
|
182
|
+
error?: string;
|
|
183
|
+
}> = [];
|
|
109
184
|
for (const oldAppDid of migratedFrom) {
|
|
110
185
|
const oldAddress = toDelegateAddress(delegator, oldAppDid);
|
|
111
186
|
try {
|
|
112
187
|
// eslint-disable-next-line no-await-in-loop
|
|
113
188
|
const { state: oldState } = await client.getDelegateState({ address: oldAddress });
|
|
189
|
+
migratedResults.push({
|
|
190
|
+
appDid: oldAppDid,
|
|
191
|
+
address: oldAddress,
|
|
192
|
+
hasState: !!oldState,
|
|
193
|
+
opsCount: oldState?.ops?.length || 0,
|
|
194
|
+
});
|
|
114
195
|
if (oldState?.ops?.length > 0) {
|
|
115
196
|
logger.info('wallet-migration: found delegation in migratedFrom', {
|
|
116
197
|
delegator,
|
|
@@ -120,6 +201,13 @@ export async function getDelegationAddressWithFallback({
|
|
|
120
201
|
return { address: oldAddress, needsBackfill: true, source: 'migrated' };
|
|
121
202
|
}
|
|
122
203
|
} catch (err) {
|
|
204
|
+
migratedResults.push({
|
|
205
|
+
appDid: oldAppDid,
|
|
206
|
+
address: oldAddress,
|
|
207
|
+
hasState: false,
|
|
208
|
+
opsCount: 0,
|
|
209
|
+
error: String(err),
|
|
210
|
+
});
|
|
123
211
|
logger.warn('wallet-migration: failed to query migrated delegation state', {
|
|
124
212
|
address: oldAddress,
|
|
125
213
|
oldAppDid,
|
|
@@ -128,7 +216,16 @@ export async function getDelegationAddressWithFallback({
|
|
|
128
216
|
}
|
|
129
217
|
}
|
|
130
218
|
|
|
131
|
-
// Not found
|
|
219
|
+
// Not found - log detailed search results
|
|
220
|
+
logger.error('wallet-migration: no delegation found after full search', {
|
|
221
|
+
delegator,
|
|
222
|
+
chainHost,
|
|
223
|
+
currentWalletAddress: wallet.address,
|
|
224
|
+
currentDelegationAddress: currentAddress,
|
|
225
|
+
currentStateResult,
|
|
226
|
+
migratedFromCount: migratedFrom.length,
|
|
227
|
+
migratedResults,
|
|
228
|
+
});
|
|
132
229
|
return null;
|
|
133
230
|
}
|
|
134
231
|
|
|
@@ -25,6 +25,7 @@ jest.mock('../../src/libs/logger', () => ({
|
|
|
25
25
|
describe('wallet-migration', () => {
|
|
26
26
|
// Mock OcapClient
|
|
27
27
|
const createMockClient = (overrides: any = {}) => ({
|
|
28
|
+
host: 'https://main.abtnetwork.io/api',
|
|
28
29
|
getAccountState: jest.fn().mockResolvedValue({
|
|
29
30
|
state: {
|
|
30
31
|
migratedFrom: ['zNKq13Dr2TBHELpLDUJFGxepiGP7YHbAVxPn', 'zNKq6yG8AVbwdRBDJSNCDVJJUQD1AXdkK7Wp'],
|
|
@@ -76,8 +77,15 @@ describe('wallet-migration', () => {
|
|
|
76
77
|
const currentWalletAddress = 'zNKcF7wyrvAvn4YaADjr4p9gpFUSHnW2aQJa';
|
|
77
78
|
const oldAppDid = 'zNKq13Dr2TBHELpLDUJFGxepiGP7YHbAVxPn';
|
|
78
79
|
|
|
79
|
-
it('should return stored address if available', async () => {
|
|
80
|
-
const mockClient = createMockClient(
|
|
80
|
+
it('should return stored address if available and valid', async () => {
|
|
81
|
+
const mockClient = createMockClient({
|
|
82
|
+
getDelegateState: jest.fn().mockImplementation(({ address }) => {
|
|
83
|
+
if (address === 'stored_delegation_address') {
|
|
84
|
+
return { state: { ops: [{ key: 'fg:x:transfer' }] } };
|
|
85
|
+
}
|
|
86
|
+
return { state: null };
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
81
89
|
|
|
82
90
|
const result = await getDelegationAddressWithFallback({
|
|
83
91
|
storedAddress: 'stored_delegation_address',
|
|
@@ -90,8 +98,34 @@ describe('wallet-migration', () => {
|
|
|
90
98
|
needsBackfill: false,
|
|
91
99
|
source: 'stored',
|
|
92
100
|
});
|
|
93
|
-
// Should
|
|
94
|
-
expect(mockClient.getDelegateState).
|
|
101
|
+
// Should verify stored address
|
|
102
|
+
expect(mockClient.getDelegateState).toHaveBeenCalledWith({ address: 'stored_delegation_address' });
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should fallback if stored address has no valid state', async () => {
|
|
106
|
+
const oldAddress = toDelegateAddress(delegator, oldAppDid);
|
|
107
|
+
const mockClient = createMockClient({
|
|
108
|
+
getDelegateState: jest.fn().mockImplementation(({ address }) => {
|
|
109
|
+
// stored address has no state, but migratedFrom address has
|
|
110
|
+
if (address === oldAddress) {
|
|
111
|
+
return { state: { ops: [{ key: 'fg:x:transfer' }] } };
|
|
112
|
+
}
|
|
113
|
+
return { state: null };
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const result = await getDelegationAddressWithFallback({
|
|
118
|
+
storedAddress: 'invalid_stored_address',
|
|
119
|
+
delegator,
|
|
120
|
+
client: mockClient as any,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Should fallback to migratedFrom
|
|
124
|
+
expect(result).toEqual({
|
|
125
|
+
address: oldAddress,
|
|
126
|
+
needsBackfill: true,
|
|
127
|
+
source: 'migrated',
|
|
128
|
+
});
|
|
95
129
|
});
|
|
96
130
|
|
|
97
131
|
it('should return current address if delegation exists on current wallet', async () => {
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.5",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"prelint": "npm run types",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"@blocklet/error": "^0.3.5",
|
|
60
60
|
"@blocklet/js-sdk": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
61
61
|
"@blocklet/logger": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
62
|
-
"@blocklet/payment-broker-client": "1.25.
|
|
63
|
-
"@blocklet/payment-react": "1.25.
|
|
64
|
-
"@blocklet/payment-vendor": "1.25.
|
|
62
|
+
"@blocklet/payment-broker-client": "1.25.5",
|
|
63
|
+
"@blocklet/payment-react": "1.25.5",
|
|
64
|
+
"@blocklet/payment-vendor": "1.25.5",
|
|
65
65
|
"@blocklet/sdk": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
66
66
|
"@blocklet/ui-react": "^3.4.7",
|
|
67
67
|
"@blocklet/uploader": "^0.3.19",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"devDependencies": {
|
|
133
133
|
"@abtnode/types": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
134
134
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
135
|
-
"@blocklet/payment-types": "1.25.
|
|
135
|
+
"@blocklet/payment-types": "1.25.5",
|
|
136
136
|
"@types/cookie-parser": "^1.4.9",
|
|
137
137
|
"@types/cors": "^2.8.19",
|
|
138
138
|
"@types/debug": "^4.1.12",
|
|
@@ -179,5 +179,5 @@
|
|
|
179
179
|
"parser": "typescript"
|
|
180
180
|
}
|
|
181
181
|
},
|
|
182
|
-
"gitHead": "
|
|
182
|
+
"gitHead": "fc70dce73c8d46dd6cd7936d188d551316cd02db"
|
|
183
183
|
}
|