payment-kit 1.16.3 → 1.16.4

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.
@@ -319,6 +319,26 @@ export async function getOwnerDid() {
319
319
  }
320
320
  }
321
321
 
322
+ export async function getDidListByRole(role: string | string[]) {
323
+ try {
324
+ if (Array.isArray(role)) {
325
+ const didSet = new Set<string>();
326
+ await Promise.all(
327
+ role.map(async (r: string) => {
328
+ const { users } = await blocklet.getUsers({ query: { role: r } });
329
+ users.forEach((u) => didSet.add(u.did));
330
+ })
331
+ );
332
+ return Array.from(didSet);
333
+ }
334
+ const { users } = await blocklet.getUsers({ query: { role } });
335
+ return users.map((x: any) => x?.did);
336
+ } catch (error) {
337
+ logger.error('getDidListByRole error', error);
338
+ return null;
339
+ }
340
+ }
341
+
322
342
  export function getSubscriptionNotificationCustomActions(
323
343
  subscription: Subscription,
324
344
  eventType: string,
@@ -2,8 +2,11 @@
2
2
  import type { Transaction } from '@ocap/client';
3
3
  import { fromAddress } from '@ocap/wallet';
4
4
 
5
+ import { toBase58 } from '@ocap/util';
6
+ import { encodeTransferItx } from 'api/src/integrations/ethereum/token';
7
+ import { waitForEvmTxConfirm, waitForEvmTxReceipt } from 'api/src/integrations/ethereum/tx';
5
8
  import type { CallbackArgs } from '../../libs/auth';
6
- import { wallet } from '../../libs/auth';
9
+ import { ethWallet, wallet } from '../../libs/auth';
7
10
  import { getGasPayerExtra } from '../../libs/payment';
8
11
  import { getTxMetadata } from '../../libs/util';
9
12
  import { invoiceQueue } from '../../queues/invoice';
@@ -59,30 +62,30 @@ export default {
59
62
  return claims;
60
63
  }
61
64
 
65
+ if (paymentMethod.type === 'ethereum') {
66
+ return {
67
+ signature: {
68
+ type: 'eth:transaction',
69
+ data: toBase58(
70
+ Buffer.from(
71
+ JSON.stringify({
72
+ network: paymentMethod.settings?.ethereum?.chain_id,
73
+ tx: encodeTransferItx(ethWallet.address, amount!, paymentCurrency.contract),
74
+ }),
75
+ 'utf-8'
76
+ )
77
+ ),
78
+ },
79
+ };
80
+ }
81
+
62
82
  throw new Error(`Payment method ${paymentMethod.type} not supported`);
63
83
  },
64
84
  onAuth: async ({ request, userDid, claims, extraParams }: CallbackArgs) => {
65
85
  const { subscriptionId, currencyId } = extraParams;
66
86
  const { invoices, paymentMethod } = await ensureSubscriptionForCollectBatch(subscriptionId, currencyId);
67
87
 
68
- if (paymentMethod.type === 'arcblock') {
69
- const client = paymentMethod.getOcapClient();
70
- const claim = claims.find((x) => x.type === 'prepareTx');
71
-
72
- const tx: Partial<Transaction> = client.decodeTx(claim.finalTx);
73
- if (claim.delegator && claim.from) {
74
- tx.delegator = claim.delegator;
75
- tx.from = claim.from;
76
- }
77
-
78
- // @ts-ignore
79
- const { buffer } = await client.encodeTransferV3Tx({ tx });
80
- const txHash = await client.sendTransferV3Tx(
81
- // @ts-ignore
82
- { tx, wallet: fromAddress(userDid) },
83
- getGasPayerExtra(buffer, client.pickGasPayerHeaders(request))
84
- );
85
-
88
+ const afterTxExecution = async (paymentDetails: any) => {
86
89
  const paymentIntents = await PaymentIntent.findAll({
87
90
  where: {
88
91
  invoice_id: invoices,
@@ -95,11 +98,7 @@ export default {
95
98
  capture_method: 'manual',
96
99
  last_payment_error: null,
97
100
  payment_details: {
98
- arcblock: {
99
- tx_hash: txHash,
100
- payer: userDid,
101
- type: 'transfer',
102
- },
101
+ [paymentMethod.type]: paymentDetails,
103
102
  },
104
103
  });
105
104
 
@@ -117,10 +116,52 @@ export default {
117
116
  }
118
117
  }
119
118
  }
119
+ };
120
+
121
+ if (paymentMethod.type === 'arcblock') {
122
+ const client = paymentMethod.getOcapClient();
123
+ const claim = claims.find((x) => x.type === 'prepareTx');
124
+
125
+ const tx: Partial<Transaction> = client.decodeTx(claim.finalTx);
126
+ if (claim.delegator && claim.from) {
127
+ tx.delegator = claim.delegator;
128
+ tx.from = claim.from;
129
+ }
130
+
131
+ // @ts-ignore
132
+ const { buffer } = await client.encodeTransferV3Tx({ tx });
133
+ const txHash = await client.sendTransferV3Tx(
134
+ // @ts-ignore
135
+ { tx, wallet: fromAddress(userDid) },
136
+ getGasPayerExtra(buffer, client.pickGasPayerHeaders(request))
137
+ );
138
+ await afterTxExecution({ tx_hash: txHash, payer: userDid, type: 'transfer' });
120
139
 
121
140
  return { hash: txHash };
122
141
  }
142
+ if (paymentMethod.type === 'ethereum') {
143
+ const client = paymentMethod.getEvmClient();
144
+ const claim = claims.find((x) => x.type === 'signature');
123
145
 
146
+ const receipt = await waitForEvmTxReceipt(client, claim.hash);
147
+ if (!receipt.status) {
148
+ throw new Error(`EVM Transaction failed: ${claim.hash}`);
149
+ }
150
+
151
+ waitForEvmTxConfirm(client, Number(receipt.blockNumber), paymentMethod.confirmation.block)
152
+ .then(async () => {
153
+ await afterTxExecution({
154
+ tx_hash: claim.hash,
155
+ block_height: receipt.blockNumber.toString(),
156
+ gas_used: receipt.gasUsed.toString(),
157
+ gas_price: receipt.gasPrice.toString(),
158
+ payer: userDid,
159
+ type: 'transfer',
160
+ });
161
+ })
162
+ .catch(console.error);
163
+ return { hash: claim.hash };
164
+ }
124
165
  throw new Error(`Payment method ${paymentMethod.type} not supported`);
125
166
  },
126
167
  };
@@ -6,7 +6,8 @@ import isObject from 'lodash/isObject';
6
6
  import pick from 'lodash/pick';
7
7
  import uniq from 'lodash/uniq';
8
8
 
9
- import { literal, OrderItem } from 'sequelize';
9
+ import { literal, Op, OrderItem } from 'sequelize';
10
+ import { BN } from '@ocap/util';
10
11
  import { createEvent } from '../libs/audit';
11
12
  import {
12
13
  ensureStripeCustomer,
@@ -1858,4 +1859,60 @@ router.get('/:id/recharge', authMine, async (req, res) => {
1858
1859
  return res.status(400).json({ error: err.message });
1859
1860
  }
1860
1861
  });
1862
+
1863
+ router.get('/:id/overdue/invoices', authPortal, async (req, res) => {
1864
+ try {
1865
+ const subscription = await Subscription.findByPk(req.params.id, {
1866
+ include: [{ model: Customer, as: 'customer' }],
1867
+ });
1868
+ if (!subscription) {
1869
+ return res.status(404).json({ error: 'Subscription not found' });
1870
+ }
1871
+ // @ts-ignore
1872
+ if (subscription.customer?.did !== req.user?.did) {
1873
+ return res.status(403).json({ error: 'You are not allowed to access this subscription' });
1874
+ }
1875
+ const { rows: invoices, count } = await Invoice.findAndCountAll({
1876
+ where: {
1877
+ subscription_id: subscription.id,
1878
+ status: ['uncollectible'],
1879
+ amount_remaining: { [Op.gt]: '0' },
1880
+ },
1881
+ include: [
1882
+ { model: PaymentCurrency, as: 'paymentCurrency' },
1883
+ { model: PaymentMethod, as: 'paymentMethod' },
1884
+ ],
1885
+ });
1886
+ if (count === 0) {
1887
+ return res.json({ subscription, invoices: [], summary: null });
1888
+ }
1889
+ const summary: Record<string, { amount: string; currency: PaymentCurrency; method: PaymentMethod }> = {};
1890
+ invoices.forEach((invoice) => {
1891
+ const key = invoice.currency_id;
1892
+ if (!summary[key]) {
1893
+ summary[key] = {
1894
+ amount: '0',
1895
+ // @ts-ignore
1896
+ currency: invoice.paymentCurrency,
1897
+ // @ts-ignore
1898
+ method: invoice.paymentMethod,
1899
+ };
1900
+ }
1901
+ if (invoice && summary[key]) {
1902
+ // @ts-ignore
1903
+ summary[key].amount = new BN(summary[key]?.amount || '0')
1904
+ .add(new BN(invoice.amount_remaining || '0'))
1905
+ .toString();
1906
+ }
1907
+ });
1908
+ return res.json({
1909
+ subscription,
1910
+ summary,
1911
+ invoices,
1912
+ });
1913
+ } catch (err) {
1914
+ console.error(err);
1915
+ return res.status(400).json({ error: err.message });
1916
+ }
1917
+ });
1861
1918
  export default router;
package/blocklet.yml CHANGED
@@ -14,7 +14,7 @@ repository:
14
14
  type: git
15
15
  url: git+https://github.com/blocklet/payment-kit.git
16
16
  specVersion: 1.2.8
17
- version: 1.16.3
17
+ version: 1.16.4
18
18
  logo: logo.png
19
19
  files:
20
20
  - dist
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payment-kit",
3
- "version": "1.16.3",
3
+ "version": "1.16.4",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "eject": "vite eject",
@@ -53,7 +53,7 @@
53
53
  "@arcblock/validator": "^1.18.147",
54
54
  "@blocklet/js-sdk": "1.16.33-beta-20241031-073543-49b1ff9b",
55
55
  "@blocklet/logger": "1.16.33-beta-20241031-073543-49b1ff9b",
56
- "@blocklet/payment-react": "1.16.3",
56
+ "@blocklet/payment-react": "1.16.4",
57
57
  "@blocklet/sdk": "1.16.33-beta-20241031-073543-49b1ff9b",
58
58
  "@blocklet/ui-react": "^2.10.67",
59
59
  "@blocklet/uploader": "^0.1.52",
@@ -120,7 +120,7 @@
120
120
  "devDependencies": {
121
121
  "@abtnode/types": "1.16.33-beta-20241031-073543-49b1ff9b",
122
122
  "@arcblock/eslint-config-ts": "^0.3.3",
123
- "@blocklet/payment-types": "1.16.3",
123
+ "@blocklet/payment-types": "1.16.4",
124
124
  "@types/cookie-parser": "^1.4.7",
125
125
  "@types/cors": "^2.8.17",
126
126
  "@types/debug": "^4.1.12",
@@ -166,5 +166,5 @@
166
166
  "parser": "typescript"
167
167
  }
168
168
  },
169
- "gitHead": "6accc56a51e4ea0906e65f69dc5f41eaa82685fb"
169
+ "gitHead": "d2c53c8bec3a4a34d0ef3a011ec215b69bc9a5ab"
170
170
  }