@4mica/sdk 0.5.6 → 1.0.1
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/README.md +82 -4
- package/dist/abi/core4mica.d.ts +0 -28
- package/dist/abi/core4mica.js +0 -36
- package/dist/abi/erc20.d.ts +10 -0
- package/dist/abi/erc20.js +13 -0
- package/dist/bls.js +13 -2
- package/dist/client/index.d.ts +48 -1
- package/dist/client/index.js +46 -0
- package/dist/client/recipient.d.ts +108 -4
- package/dist/client/recipient.js +129 -6
- package/dist/client/user.d.ts +78 -2
- package/dist/client/user.js +83 -28
- package/dist/config.d.ts +50 -0
- package/dist/config.js +42 -1
- package/dist/contract.d.ts +10 -0
- package/dist/contract.js +74 -24
- package/dist/errors.d.ts +15 -0
- package/dist/errors.js +15 -0
- package/dist/guarantee.d.ts +22 -0
- package/dist/guarantee.js +209 -29
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models.d.ts +108 -0
- package/dist/models.js +120 -1
- package/dist/payment.d.ts +66 -4
- package/dist/payment.js +39 -5
- package/dist/rpc.d.ts +2 -2
- package/dist/rpc.js +5 -2
- package/dist/signing.d.ts +89 -12
- package/dist/signing.js +109 -30
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +13 -5
- package/dist/validation.d.ts +32 -0
- package/dist/validation.js +82 -0
- package/dist/x402/index.d.ts +70 -2
- package/dist/x402/index.js +101 -1
- package/dist/x402/models.d.ts +8 -2
- package/package.json +6 -1
package/dist/client/recipient.js
CHANGED
|
@@ -9,6 +9,7 @@ const models_1 = require("../models");
|
|
|
9
9
|
const debug_1 = require("../debug");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const shared_1 = require("./shared");
|
|
12
|
+
/** Recipient-side operations: tab management, guarantee issuance, remuneration. */
|
|
12
13
|
class RecipientClient {
|
|
13
14
|
client;
|
|
14
15
|
constructor(client) {
|
|
@@ -20,6 +21,17 @@ class RecipientClient {
|
|
|
20
21
|
get guaranteeDomain() {
|
|
21
22
|
return this.client.guaranteeDomain;
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a payment tab via the core RPC.
|
|
26
|
+
*
|
|
27
|
+
* @param userAddress - Address of the payer.
|
|
28
|
+
* @param recipientAddress - Address of the recipient.
|
|
29
|
+
* @param erc20Token - ERC20 token address for the tab, or `null`/`undefined` for ETH.
|
|
30
|
+
* @param ttl - Optional time-to-live in seconds.
|
|
31
|
+
* @returns `{ tabId, assetAddress, nextReqId }` — the tab ID, the asset address as stored
|
|
32
|
+
* by the core (use this for all subsequent claims), and the first request ID to use.
|
|
33
|
+
* @throws {@link RpcError} if the request fails.
|
|
34
|
+
*/
|
|
23
35
|
async createTab(userAddress, recipientAddress, erc20Token, ttl) {
|
|
24
36
|
const body = {
|
|
25
37
|
user_address: (0, utils_1.normalizeAddress)(userAddress),
|
|
@@ -31,12 +43,39 @@ class RecipientClient {
|
|
|
31
43
|
const record = result;
|
|
32
44
|
const tabIdRaw = record.id ?? record.tabId ?? record.tab_id;
|
|
33
45
|
const tabId = (0, shared_1.isNumericLike)(tabIdRaw) ? tabIdRaw : 0;
|
|
34
|
-
|
|
46
|
+
const erc20Raw = record.erc20_token ?? record.erc20Token;
|
|
47
|
+
const assetAddress = typeof erc20Raw === 'string' && erc20Raw
|
|
48
|
+
? erc20Raw
|
|
49
|
+
: '0x0000000000000000000000000000000000000000';
|
|
50
|
+
const nextReqIdRaw = record.next_req_id ?? record.nextReqId ?? 0;
|
|
51
|
+
return {
|
|
52
|
+
tabId: (0, utils_1.parseU256)(tabId),
|
|
53
|
+
assetAddress,
|
|
54
|
+
nextReqId: (0, utils_1.parseU256)((0, shared_1.isNumericLike)(nextReqIdRaw) ? nextReqIdRaw : 0),
|
|
55
|
+
};
|
|
35
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Query the on-chain payment status of a tab.
|
|
59
|
+
*
|
|
60
|
+
* @param tabId - Tab identifier.
|
|
61
|
+
* @returns `{ paid, remunerated, asset }`.
|
|
62
|
+
*/
|
|
36
63
|
async getTabPaymentStatus(tabId) {
|
|
37
64
|
const status = await this.client.gateway.getPaymentStatus(tabId);
|
|
38
65
|
return (0, shared_1.tabStatusFromRpc)(status);
|
|
39
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Issue a BLS-signed payment guarantee certificate via the core RPC.
|
|
69
|
+
*
|
|
70
|
+
* The returned {@link BLSCert} can be stored and later passed to
|
|
71
|
+
* {@link remunerate} to claim the payment on-chain.
|
|
72
|
+
*
|
|
73
|
+
* @param claims - Signed payment claims (V1 or V2).
|
|
74
|
+
* @param signature - ECDSA signature hex string from the payer.
|
|
75
|
+
* @param scheme - Signing scheme used to produce the signature.
|
|
76
|
+
* @returns BLS certificate with ABI-encoded claims and BLS signature.
|
|
77
|
+
* @throws {@link RpcError} if the core service rejects the request.
|
|
78
|
+
*/
|
|
40
79
|
async issuePaymentGuarantee(claims, signature, scheme) {
|
|
41
80
|
const payload = (0, payment_1.buildPaymentPayload)(claims, signature, scheme);
|
|
42
81
|
const cert = await this.client.rpc.issueGuarantee(payload);
|
|
@@ -45,19 +84,59 @@ class RecipientClient {
|
|
|
45
84
|
const signatureOut = typeof record.signature === 'string' ? record.signature : '';
|
|
46
85
|
return { claims: certClaims, signature: signatureOut };
|
|
47
86
|
}
|
|
48
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Verify and decode a BLS guarantee certificate.
|
|
89
|
+
*
|
|
90
|
+
* Decodes the ABI-encoded claims and validates the domain separator against
|
|
91
|
+
* the on-chain configuration. For V2 certificates, the active V2 domain is
|
|
92
|
+
* fetched from the contract and verified to be enabled.
|
|
93
|
+
*
|
|
94
|
+
* @param cert - BLS certificate (hex-encoded claims + hex-encoded signature).
|
|
95
|
+
* @returns Decoded {@link PaymentGuaranteeClaims}, including validation policy for V2.
|
|
96
|
+
* @throws {@link VerificationError} on domain mismatch, invalid length, or disabled version.
|
|
97
|
+
*/
|
|
98
|
+
async verifyPaymentGuarantee(cert) {
|
|
49
99
|
const claims = (0, guarantee_1.decodeGuaranteeClaims)(cert.claims);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
100
|
+
let expectedDomain;
|
|
101
|
+
if (claims.version === 2) {
|
|
102
|
+
const { domainSeparator, enabled } = await this.client.gateway.getGuaranteeVersionConfig(2);
|
|
103
|
+
if (!enabled) {
|
|
104
|
+
throw new errors_1.VerificationError('guarantee version 2 is not enabled on-chain');
|
|
105
|
+
}
|
|
106
|
+
expectedDomain = domainSeparator;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
expectedDomain = this.guaranteeDomain;
|
|
110
|
+
}
|
|
111
|
+
const domainHex = expectedDomain.startsWith('0x')
|
|
112
|
+
? expectedDomain.slice(2)
|
|
113
|
+
: Buffer.from(expectedDomain).toString('hex');
|
|
114
|
+
if (domainHex.length !== 64) {
|
|
115
|
+
throw new errors_1.VerificationError(`guarantee domain separator has invalid length: expected 32 bytes, got ${domainHex.length / 2}`);
|
|
116
|
+
}
|
|
53
117
|
const claimsHex = Buffer.from(claims.domain).toString('hex');
|
|
54
118
|
if (claimsHex !== domainHex) {
|
|
55
119
|
throw new errors_1.VerificationError('guarantee domain mismatch');
|
|
56
120
|
}
|
|
57
121
|
return claims;
|
|
58
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Claim payment on-chain by submitting a verified BLS certificate.
|
|
125
|
+
*
|
|
126
|
+
* Verifies the certificate first (see {@link verifyPaymentGuarantee}), then
|
|
127
|
+
* converts the BLS signature into the G2 coordinate words expected by the
|
|
128
|
+
* contract and submits the `remunerate` transaction.
|
|
129
|
+
*
|
|
130
|
+
* Requires the optional `@noble/curves` package for BLS point decompression.
|
|
131
|
+
*
|
|
132
|
+
* @param cert - BLS certificate to settle.
|
|
133
|
+
* @param waitOptions - Optional timeout/polling overrides for receipt polling.
|
|
134
|
+
* @throws {@link VerificationError} if the certificate is invalid or `claims`/`signature`
|
|
135
|
+
* are not hex strings.
|
|
136
|
+
* @throws {@link ContractError} if the contract call fails.
|
|
137
|
+
*/
|
|
59
138
|
async remunerate(cert, waitOptions) {
|
|
60
|
-
this.verifyPaymentGuarantee(cert);
|
|
139
|
+
await this.verifyPaymentGuarantee(cert);
|
|
61
140
|
const describeValue = (value) => {
|
|
62
141
|
if (value === null)
|
|
63
142
|
return 'null';
|
|
@@ -88,42 +167,86 @@ class RecipientClient {
|
|
|
88
167
|
}
|
|
89
168
|
return this.client.gateway.remunerate(claimsBytes, sigWords);
|
|
90
169
|
}
|
|
170
|
+
/** List all tabs for this recipient that have been settled on-chain. */
|
|
91
171
|
async listSettledTabs() {
|
|
92
172
|
const tabs = await this.client.rpc.listSettledTabs(this.recipientAddress);
|
|
93
173
|
return tabs.map((t) => models_1.TabInfo.fromRpc(t));
|
|
94
174
|
}
|
|
175
|
+
/** List all tabs with outstanding (un-remunerated) guarantees for this recipient. */
|
|
95
176
|
async listPendingRemunerations() {
|
|
96
177
|
const items = await this.client.rpc.listPendingRemunerations(this.recipientAddress);
|
|
97
178
|
return items.map((item) => models_1.PendingRemunerationInfo.fromRpc(item));
|
|
98
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Fetch a single tab by ID.
|
|
182
|
+
*
|
|
183
|
+
* @param tabId - Tab identifier.
|
|
184
|
+
* @returns The tab, or `null` if not found.
|
|
185
|
+
*/
|
|
99
186
|
async getTab(tabId) {
|
|
100
187
|
const result = await this.client.rpc.getTab(tabId);
|
|
101
188
|
return result ? models_1.TabInfo.fromRpc(result) : null;
|
|
102
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* List all tabs belonging to this recipient.
|
|
192
|
+
*
|
|
193
|
+
* @param settlementStatuses - Optional filter on settlement status (e.g. `['PENDING']`).
|
|
194
|
+
*/
|
|
103
195
|
async listRecipientTabs(settlementStatuses) {
|
|
104
196
|
const tabs = await this.client.rpc.listRecipientTabs(this.recipientAddress, settlementStatuses);
|
|
105
197
|
return tabs.map((t) => models_1.TabInfo.fromRpc(t));
|
|
106
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* List all guarantee requests associated with a tab.
|
|
201
|
+
*
|
|
202
|
+
* @param tabId - Tab identifier.
|
|
203
|
+
*/
|
|
107
204
|
async getTabGuarantees(tabId) {
|
|
108
205
|
const guarantees = await this.client.rpc.getTabGuarantees(tabId);
|
|
109
206
|
return guarantees.map((g) => models_1.GuaranteeInfo.fromRpc(g));
|
|
110
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Fetch the most recent guarantee for a tab.
|
|
210
|
+
*
|
|
211
|
+
* @param tabId - Tab identifier.
|
|
212
|
+
* @returns The latest {@link GuaranteeInfo}, or `null` if none exists.
|
|
213
|
+
*/
|
|
111
214
|
async getLatestGuarantee(tabId) {
|
|
112
215
|
const result = await this.client.rpc.getLatestGuarantee(tabId);
|
|
113
216
|
return result ? models_1.GuaranteeInfo.fromRpc(result) : null;
|
|
114
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Fetch a specific guarantee by tab ID and request ID.
|
|
220
|
+
*
|
|
221
|
+
* @param tabId - Tab identifier.
|
|
222
|
+
* @param reqId - Guarantee request identifier.
|
|
223
|
+
* @returns The {@link GuaranteeInfo}, or `null` if not found.
|
|
224
|
+
*/
|
|
115
225
|
async getGuarantee(tabId, reqId) {
|
|
116
226
|
const result = await this.client.rpc.getGuarantee(tabId, reqId);
|
|
117
227
|
return result ? models_1.GuaranteeInfo.fromRpc(result) : null;
|
|
118
228
|
}
|
|
229
|
+
/** List all on-chain payments received by this recipient. */
|
|
119
230
|
async listRecipientPayments() {
|
|
120
231
|
const payments = await this.client.rpc.listRecipientPayments(this.recipientAddress);
|
|
121
232
|
return payments.map((p) => models_1.RecipientPaymentInfo.fromRpc(p));
|
|
122
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* List collateral deposit/withdrawal events associated with a tab.
|
|
236
|
+
*
|
|
237
|
+
* @param tabId - Tab identifier.
|
|
238
|
+
*/
|
|
123
239
|
async getCollateralEventsForTab(tabId) {
|
|
124
240
|
const events = await this.client.rpc.getCollateralEventsForTab(tabId);
|
|
125
241
|
return events.map((ev) => models_1.CollateralEventInfo.fromRpc(ev));
|
|
126
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Fetch the collateral balance a user has locked for a specific asset.
|
|
245
|
+
*
|
|
246
|
+
* @param userAddress - Address of the payer.
|
|
247
|
+
* @param assetAddress - ERC20 token address, or zero address for ETH.
|
|
248
|
+
* @returns Balance info, or `null` if no record exists.
|
|
249
|
+
*/
|
|
127
250
|
async getUserAssetBalance(userAddress, assetAddress) {
|
|
128
251
|
const balance = await this.client.rpc.getUserAssetBalance(userAddress, assetAddress);
|
|
129
252
|
return balance ? models_1.AssetBalanceInfo.fromRpc(balance) : null;
|
package/dist/client/user.d.ts
CHANGED
|
@@ -1,17 +1,93 @@
|
|
|
1
|
-
import { PaymentGuaranteeRequestClaims, PaymentSignature, SigningScheme, TabPaymentStatus, UserInfo } from '../models';
|
|
1
|
+
import { PaymentGuaranteeRequestClaims, PaymentGuaranteeRequestClaimsV2, PaymentSignature, SigningScheme, TabPaymentStatus, UserInfo } from '../models';
|
|
2
2
|
import type { TxReceiptWaitOptions } from '../contract';
|
|
3
3
|
import type { Client } from './index';
|
|
4
|
+
/** Payer-side operations: collateral management, payment signing, withdrawals. */
|
|
4
5
|
export declare class UserClient {
|
|
5
6
|
private client;
|
|
6
7
|
constructor(client: Client);
|
|
8
|
+
/** 32-byte V1 guarantee domain separator (hex-prefixed). */
|
|
7
9
|
get guaranteeDomain(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Approve the Core4Mica contract to spend an ERC20 token on your behalf.
|
|
12
|
+
* Call this before {@link deposit} for ERC20 deposits.
|
|
13
|
+
*
|
|
14
|
+
* @param token - ERC20 token contract address.
|
|
15
|
+
* @param amount - Amount to approve (in token base units).
|
|
16
|
+
* @param waitOptions - Optional timeout/polling overrides for receipt polling.
|
|
17
|
+
*/
|
|
8
18
|
approveErc20(token: string, amount: number | bigint | string, waitOptions?: TxReceiptWaitOptions): Promise<import("viem").TransactionReceipt>;
|
|
19
|
+
/**
|
|
20
|
+
* Deposit collateral into the Core4Mica contract.
|
|
21
|
+
*
|
|
22
|
+
* @param amount - Amount to deposit (in wei for ETH, base units for ERC20).
|
|
23
|
+
* @param erc20Token - ERC20 token address. Omit to deposit ETH.
|
|
24
|
+
* Call {@link approveErc20} first when depositing ERC20.
|
|
25
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
26
|
+
*/
|
|
9
27
|
deposit(amount: number | bigint | string, erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<import("viem").TransactionReceipt>;
|
|
28
|
+
/**
|
|
29
|
+
* Fetch all asset positions for the current signer.
|
|
30
|
+
*
|
|
31
|
+
* @returns Array of positions — one entry per deposited asset, including
|
|
32
|
+
* locked collateral and any pending withdrawal.
|
|
33
|
+
* @throws {@link ContractError} if the contract call fails.
|
|
34
|
+
*/
|
|
10
35
|
getUser(): Promise<UserInfo[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Query the on-chain payment status of a tab.
|
|
38
|
+
*
|
|
39
|
+
* @param tabId - Tab identifier.
|
|
40
|
+
* @returns `{ paid, remunerated, asset }` — cumulative amount paid, whether
|
|
41
|
+
* it has been remunerated on-chain, and the asset address.
|
|
42
|
+
*/
|
|
11
43
|
getTabPaymentStatus(tabId: number | bigint): Promise<TabPaymentStatus>;
|
|
12
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Sign a payment guarantee request with the configured signer.
|
|
46
|
+
*
|
|
47
|
+
* @param claims - V1 or V2 payment claims. Build V1 with
|
|
48
|
+
* {@link PaymentGuaranteeRequestClaims.new}; build V2 with
|
|
49
|
+
* {@link PaymentGuaranteeRequestClaimsV2} (requires validation policy fields).
|
|
50
|
+
* @param scheme - Signing scheme. Defaults to `EIP712`.
|
|
51
|
+
* Use `EIP191` for wallets that do not support typed data.
|
|
52
|
+
* @returns 65-byte ECDSA signature plus the scheme used.
|
|
53
|
+
* @throws {@link SigningError} if the signer address does not match `claims.userAddress`
|
|
54
|
+
* or the signing scheme is not supported by the account.
|
|
55
|
+
*/
|
|
56
|
+
signPayment(claims: PaymentGuaranteeRequestClaims | PaymentGuaranteeRequestClaimsV2, scheme?: SigningScheme): Promise<PaymentSignature>;
|
|
57
|
+
/**
|
|
58
|
+
* Pay a tab by transferring collateral to the recipient.
|
|
59
|
+
*
|
|
60
|
+
* Routes to `payTabErc20` when `erc20Token` is provided, otherwise `payTabEth`.
|
|
61
|
+
*
|
|
62
|
+
* @param tabId - Tab identifier.
|
|
63
|
+
* @param reqId - Request ID from the latest guarantee (used for ETH payment memo).
|
|
64
|
+
* @param amount - Amount to pay (in token base units / wei).
|
|
65
|
+
* @param recipientAddress - Address of the recipient.
|
|
66
|
+
* @param erc20Token - ERC20 token address. Omit to pay in ETH.
|
|
67
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
68
|
+
*/
|
|
13
69
|
payTab(tabId: number | bigint, reqId: number | bigint, amount: number | bigint | string, recipientAddress: string, erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<import("viem").TransactionReceipt>;
|
|
70
|
+
/**
|
|
71
|
+
* Initiate a collateral withdrawal request. The withdrawal is subject to an
|
|
72
|
+
* on-chain timelock before it can be finalised.
|
|
73
|
+
*
|
|
74
|
+
* @param amount - Amount to withdraw (base units / wei).
|
|
75
|
+
* @param erc20Token - ERC20 token address. Omit to withdraw ETH.
|
|
76
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
77
|
+
*/
|
|
14
78
|
requestWithdrawal(amount: number | bigint | string, erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<import("viem").TransactionReceipt>;
|
|
79
|
+
/**
|
|
80
|
+
* Cancel a pending withdrawal request before the timelock expires.
|
|
81
|
+
*
|
|
82
|
+
* @param erc20Token - ERC20 token address. Omit to cancel an ETH withdrawal.
|
|
83
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
84
|
+
*/
|
|
15
85
|
cancelWithdrawal(erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<import("viem").TransactionReceipt>;
|
|
86
|
+
/**
|
|
87
|
+
* Finalise a withdrawal after the timelock has elapsed.
|
|
88
|
+
*
|
|
89
|
+
* @param erc20Token - ERC20 token address. Omit to finalise an ETH withdrawal.
|
|
90
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
91
|
+
*/
|
|
16
92
|
finalizeWithdrawal(erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<import("viem").TransactionReceipt>;
|
|
17
93
|
}
|
package/dist/client/user.js
CHANGED
|
@@ -4,26 +4,45 @@ exports.UserClient = void 0;
|
|
|
4
4
|
const models_1 = require("../models");
|
|
5
5
|
const shared_1 = require("./shared");
|
|
6
6
|
const utils_1 = require("../utils");
|
|
7
|
+
/** Payer-side operations: collateral management, payment signing, withdrawals. */
|
|
7
8
|
class UserClient {
|
|
8
9
|
client;
|
|
9
10
|
constructor(client) {
|
|
10
11
|
this.client = client;
|
|
11
12
|
}
|
|
13
|
+
/** 32-byte V1 guarantee domain separator (hex-prefixed). */
|
|
12
14
|
get guaranteeDomain() {
|
|
13
15
|
return this.client.guaranteeDomain;
|
|
14
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Approve the Core4Mica contract to spend an ERC20 token on your behalf.
|
|
19
|
+
* Call this before {@link deposit} for ERC20 deposits.
|
|
20
|
+
*
|
|
21
|
+
* @param token - ERC20 token contract address.
|
|
22
|
+
* @param amount - Amount to approve (in token base units).
|
|
23
|
+
* @param waitOptions - Optional timeout/polling overrides for receipt polling.
|
|
24
|
+
*/
|
|
15
25
|
async approveErc20(token, amount, waitOptions) {
|
|
16
|
-
|
|
17
|
-
return this.client.gateway.approveErc20(token, amount, waitOptions);
|
|
18
|
-
}
|
|
19
|
-
return this.client.gateway.approveErc20(token, amount);
|
|
26
|
+
return this.client.gateway.approveErc20(token, amount, waitOptions);
|
|
20
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Deposit collateral into the Core4Mica contract.
|
|
30
|
+
*
|
|
31
|
+
* @param amount - Amount to deposit (in wei for ETH, base units for ERC20).
|
|
32
|
+
* @param erc20Token - ERC20 token address. Omit to deposit ETH.
|
|
33
|
+
* Call {@link approveErc20} first when depositing ERC20.
|
|
34
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
35
|
+
*/
|
|
21
36
|
async deposit(amount, erc20Token, waitOptions) {
|
|
22
|
-
|
|
23
|
-
return this.client.gateway.deposit(amount, erc20Token, waitOptions);
|
|
24
|
-
}
|
|
25
|
-
return this.client.gateway.deposit(amount, erc20Token);
|
|
37
|
+
return this.client.gateway.deposit(amount, erc20Token, waitOptions);
|
|
26
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Fetch all asset positions for the current signer.
|
|
41
|
+
*
|
|
42
|
+
* @returns Array of positions — one entry per deposited asset, including
|
|
43
|
+
* locked collateral and any pending withdrawal.
|
|
44
|
+
* @throws {@link ContractError} if the contract call fails.
|
|
45
|
+
*/
|
|
27
46
|
async getUser() {
|
|
28
47
|
const assets = await this.client.gateway.getUserAssets();
|
|
29
48
|
return assets.map((a) => ({
|
|
@@ -33,42 +52,78 @@ class UserClient {
|
|
|
33
52
|
withdrawalRequestTimestamp: Number(a.withdrawalRequestTimestamp),
|
|
34
53
|
}));
|
|
35
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Query the on-chain payment status of a tab.
|
|
57
|
+
*
|
|
58
|
+
* @param tabId - Tab identifier.
|
|
59
|
+
* @returns `{ paid, remunerated, asset }` — cumulative amount paid, whether
|
|
60
|
+
* it has been remunerated on-chain, and the asset address.
|
|
61
|
+
*/
|
|
36
62
|
async getTabPaymentStatus(tabId) {
|
|
37
63
|
const status = await this.client.gateway.getPaymentStatus(tabId);
|
|
38
64
|
return (0, shared_1.tabStatusFromRpc)(status);
|
|
39
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Sign a payment guarantee request with the configured signer.
|
|
68
|
+
*
|
|
69
|
+
* @param claims - V1 or V2 payment claims. Build V1 with
|
|
70
|
+
* {@link PaymentGuaranteeRequestClaims.new}; build V2 with
|
|
71
|
+
* {@link PaymentGuaranteeRequestClaimsV2} (requires validation policy fields).
|
|
72
|
+
* @param scheme - Signing scheme. Defaults to `EIP712`.
|
|
73
|
+
* Use `EIP191` for wallets that do not support typed data.
|
|
74
|
+
* @returns 65-byte ECDSA signature plus the scheme used.
|
|
75
|
+
* @throws {@link SigningError} if the signer address does not match `claims.userAddress`
|
|
76
|
+
* or the signing scheme is not supported by the account.
|
|
77
|
+
*/
|
|
40
78
|
async signPayment(claims, scheme = models_1.SigningScheme.EIP712) {
|
|
41
79
|
return this.client.signer.signRequest(this.client.params, claims, scheme);
|
|
42
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Pay a tab by transferring collateral to the recipient.
|
|
83
|
+
*
|
|
84
|
+
* Routes to `payTabErc20` when `erc20Token` is provided, otherwise `payTabEth`.
|
|
85
|
+
*
|
|
86
|
+
* @param tabId - Tab identifier.
|
|
87
|
+
* @param reqId - Request ID from the latest guarantee (used for ETH payment memo).
|
|
88
|
+
* @param amount - Amount to pay (in token base units / wei).
|
|
89
|
+
* @param recipientAddress - Address of the recipient.
|
|
90
|
+
* @param erc20Token - ERC20 token address. Omit to pay in ETH.
|
|
91
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
92
|
+
*/
|
|
43
93
|
async payTab(tabId, reqId, amount, recipientAddress, erc20Token, waitOptions) {
|
|
44
94
|
if (erc20Token) {
|
|
45
|
-
|
|
46
|
-
return this.client.gateway.payTabErc20(tabId, amount, erc20Token, recipientAddress, waitOptions);
|
|
47
|
-
}
|
|
48
|
-
return this.client.gateway.payTabErc20(tabId, amount, erc20Token, recipientAddress);
|
|
49
|
-
}
|
|
50
|
-
if (waitOptions) {
|
|
51
|
-
return this.client.gateway.payTabEth(tabId, reqId, amount, recipientAddress, waitOptions);
|
|
95
|
+
return this.client.gateway.payTabErc20(tabId, amount, erc20Token, recipientAddress, waitOptions);
|
|
52
96
|
}
|
|
53
|
-
return this.client.gateway.payTabEth(tabId, reqId, amount, recipientAddress);
|
|
97
|
+
return this.client.gateway.payTabEth(tabId, reqId, amount, recipientAddress, waitOptions);
|
|
54
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Initiate a collateral withdrawal request. The withdrawal is subject to an
|
|
101
|
+
* on-chain timelock before it can be finalised.
|
|
102
|
+
*
|
|
103
|
+
* @param amount - Amount to withdraw (base units / wei).
|
|
104
|
+
* @param erc20Token - ERC20 token address. Omit to withdraw ETH.
|
|
105
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
106
|
+
*/
|
|
55
107
|
async requestWithdrawal(amount, erc20Token, waitOptions) {
|
|
56
|
-
|
|
57
|
-
return this.client.gateway.requestWithdrawal(amount, erc20Token, waitOptions);
|
|
58
|
-
}
|
|
59
|
-
return this.client.gateway.requestWithdrawal(amount, erc20Token);
|
|
108
|
+
return this.client.gateway.requestWithdrawal(amount, erc20Token, waitOptions);
|
|
60
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Cancel a pending withdrawal request before the timelock expires.
|
|
112
|
+
*
|
|
113
|
+
* @param erc20Token - ERC20 token address. Omit to cancel an ETH withdrawal.
|
|
114
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
115
|
+
*/
|
|
61
116
|
async cancelWithdrawal(erc20Token, waitOptions) {
|
|
62
|
-
|
|
63
|
-
return this.client.gateway.cancelWithdrawal(erc20Token, waitOptions);
|
|
64
|
-
}
|
|
65
|
-
return this.client.gateway.cancelWithdrawal(erc20Token);
|
|
117
|
+
return this.client.gateway.cancelWithdrawal(erc20Token, waitOptions);
|
|
66
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Finalise a withdrawal after the timelock has elapsed.
|
|
121
|
+
*
|
|
122
|
+
* @param erc20Token - ERC20 token address. Omit to finalise an ETH withdrawal.
|
|
123
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
124
|
+
*/
|
|
67
125
|
async finalizeWithdrawal(erc20Token, waitOptions) {
|
|
68
|
-
|
|
69
|
-
return this.client.gateway.finalizeWithdrawal(erc20Token, waitOptions);
|
|
70
|
-
}
|
|
71
|
-
return this.client.gateway.finalizeWithdrawal(erc20Token);
|
|
126
|
+
return this.client.gateway.finalizeWithdrawal(erc20Token, waitOptions);
|
|
72
127
|
}
|
|
73
128
|
}
|
|
74
129
|
exports.UserClient = UserClient;
|
package/dist/config.d.ts
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
import { Account } from 'viem/accounts';
|
|
2
|
+
/** Validated configuration used to construct a {@link Client}. Produced by {@link ConfigBuilder.build}. */
|
|
2
3
|
export interface Config {
|
|
4
|
+
/** URL of the 4Mica core RPC service. */
|
|
3
5
|
rpcUrl: string;
|
|
6
|
+
/** viem `Account` used to sign payments and authenticate requests. */
|
|
4
7
|
signer: Account;
|
|
8
|
+
/** Override for the Ethereum HTTP RPC URL (defaults to the value returned by the core service). */
|
|
5
9
|
ethereumHttpRpcUrl?: string;
|
|
10
|
+
/** Override for the Core4Mica contract address (defaults to the value returned by the core service). */
|
|
6
11
|
contractAddress?: string;
|
|
12
|
+
/** API key for admin-scoped RPC endpoints. */
|
|
7
13
|
adminApiKey?: string;
|
|
14
|
+
/** Static bearer token for authenticated RPC calls. Mutually exclusive with SIWE auth. */
|
|
8
15
|
bearerToken?: string;
|
|
16
|
+
/** URL of the SIWE authentication endpoint. Defaults to `rpcUrl` when auth is enabled. */
|
|
9
17
|
authUrl?: string;
|
|
18
|
+
/** Seconds before token expiry at which the auth session proactively refreshes. Defaults to 60. */
|
|
10
19
|
authRefreshMarginSecs?: number;
|
|
11
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Fluent builder for {@link Config}.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const cfg = new ConfigBuilder()
|
|
27
|
+
* .walletPrivateKey('0x...')
|
|
28
|
+
* .build();
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* All fields can also be supplied from environment variables via {@link fromEnv}.
|
|
32
|
+
*/
|
|
12
33
|
export declare class ConfigBuilder {
|
|
13
34
|
private _rpcUrl;
|
|
14
35
|
private _walletPrivateKey;
|
|
@@ -20,16 +41,45 @@ export declare class ConfigBuilder {
|
|
|
20
41
|
private _authEnabled;
|
|
21
42
|
private _authUrl?;
|
|
22
43
|
private _authRefreshMarginSecs?;
|
|
44
|
+
/** Override the 4Mica core RPC URL. Defaults to `https://api.4mica.xyz/`. */
|
|
23
45
|
rpcUrl(value: string): ConfigBuilder;
|
|
46
|
+
/** Set the wallet private key (hex string). Mutually exclusive with {@link signer}. */
|
|
24
47
|
walletPrivateKey(value: string): ConfigBuilder;
|
|
48
|
+
/** Set a pre-built viem `Account` directly. Mutually exclusive with {@link walletPrivateKey}. */
|
|
25
49
|
signer(value: Account): ConfigBuilder;
|
|
50
|
+
/** Override the Ethereum HTTP RPC URL used for on-chain calls. */
|
|
26
51
|
ethereumHttpRpcUrl(value: string): ConfigBuilder;
|
|
52
|
+
/** Override the Core4Mica contract address. */
|
|
27
53
|
contractAddress(value: string): ConfigBuilder;
|
|
54
|
+
/** Set an admin API key for privileged RPC endpoints. */
|
|
28
55
|
adminApiKey(value: string): ConfigBuilder;
|
|
56
|
+
/** Set a static bearer token for authenticated RPC calls. Disables SIWE auth. */
|
|
29
57
|
bearerToken(value: string): ConfigBuilder;
|
|
58
|
+
/** Enable SIWE authentication using the default RPC URL as the auth endpoint. Auth is enabled by default; this is a no-op unless you previously called a method that disabled it. */
|
|
30
59
|
enableAuth(): ConfigBuilder;
|
|
60
|
+
/** Set a custom SIWE authentication endpoint and enable auth. */
|
|
31
61
|
authUrl(value: string): ConfigBuilder;
|
|
62
|
+
/** Set the number of seconds before token expiry at which the session proactively refreshes. Enables auth. */
|
|
32
63
|
authRefreshMarginSecs(value: number): ConfigBuilder;
|
|
64
|
+
/**
|
|
65
|
+
* Load configuration from environment variables.
|
|
66
|
+
*
|
|
67
|
+
* Recognised variables:
|
|
68
|
+
* - `4MICA_RPC_URL`
|
|
69
|
+
* - `4MICA_WALLET_PRIVATE_KEY`
|
|
70
|
+
* - `4MICA_ETHEREUM_HTTP_RPC_URL`
|
|
71
|
+
* - `4MICA_CONTRACT_ADDRESS`
|
|
72
|
+
* - `4MICA_ADMIN_API_KEY`
|
|
73
|
+
* - `4MICA_BEARER_TOKEN`
|
|
74
|
+
* - `4MICA_AUTH_URL`
|
|
75
|
+
* - `4MICA_AUTH_REFRESH_MARGIN_SECS`
|
|
76
|
+
*/
|
|
33
77
|
fromEnv(): ConfigBuilder;
|
|
78
|
+
/**
|
|
79
|
+
* Validate all settings and return an immutable {@link Config}.
|
|
80
|
+
*
|
|
81
|
+
* @throws {@link ConfigError} if required fields are missing, URLs are invalid,
|
|
82
|
+
* or the auth refresh margin is not a finite non-negative number.
|
|
83
|
+
*/
|
|
34
84
|
build(): Config;
|
|
35
85
|
}
|
package/dist/config.js
CHANGED
|
@@ -4,6 +4,18 @@ exports.ConfigBuilder = void 0;
|
|
|
4
4
|
const accounts_1 = require("viem/accounts");
|
|
5
5
|
const errors_1 = require("./errors");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
|
+
/**
|
|
8
|
+
* Fluent builder for {@link Config}.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const cfg = new ConfigBuilder()
|
|
13
|
+
* .walletPrivateKey('0x...')
|
|
14
|
+
* .build();
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* All fields can also be supplied from environment variables via {@link fromEnv}.
|
|
18
|
+
*/
|
|
7
19
|
class ConfigBuilder {
|
|
8
20
|
_rpcUrl = 'https://api.4mica.xyz/';
|
|
9
21
|
_walletPrivateKey;
|
|
@@ -12,51 +24,74 @@ class ConfigBuilder {
|
|
|
12
24
|
_contractAddress;
|
|
13
25
|
_adminApiKey;
|
|
14
26
|
_bearerToken;
|
|
15
|
-
_authEnabled =
|
|
27
|
+
_authEnabled = true;
|
|
16
28
|
_authUrl;
|
|
17
29
|
_authRefreshMarginSecs;
|
|
30
|
+
/** Override the 4Mica core RPC URL. Defaults to `https://api.4mica.xyz/`. */
|
|
18
31
|
rpcUrl(value) {
|
|
19
32
|
this._rpcUrl = value;
|
|
20
33
|
return this;
|
|
21
34
|
}
|
|
35
|
+
/** Set the wallet private key (hex string). Mutually exclusive with {@link signer}. */
|
|
22
36
|
walletPrivateKey(value) {
|
|
23
37
|
this._walletPrivateKey = value;
|
|
24
38
|
return this;
|
|
25
39
|
}
|
|
40
|
+
/** Set a pre-built viem `Account` directly. Mutually exclusive with {@link walletPrivateKey}. */
|
|
26
41
|
signer(value) {
|
|
27
42
|
this._signer = value;
|
|
28
43
|
return this;
|
|
29
44
|
}
|
|
45
|
+
/** Override the Ethereum HTTP RPC URL used for on-chain calls. */
|
|
30
46
|
ethereumHttpRpcUrl(value) {
|
|
31
47
|
this._ethereumHttpRpcUrl = value;
|
|
32
48
|
return this;
|
|
33
49
|
}
|
|
50
|
+
/** Override the Core4Mica contract address. */
|
|
34
51
|
contractAddress(value) {
|
|
35
52
|
this._contractAddress = value;
|
|
36
53
|
return this;
|
|
37
54
|
}
|
|
55
|
+
/** Set an admin API key for privileged RPC endpoints. */
|
|
38
56
|
adminApiKey(value) {
|
|
39
57
|
this._adminApiKey = value;
|
|
40
58
|
return this;
|
|
41
59
|
}
|
|
60
|
+
/** Set a static bearer token for authenticated RPC calls. Disables SIWE auth. */
|
|
42
61
|
bearerToken(value) {
|
|
43
62
|
this._bearerToken = value;
|
|
44
63
|
return this;
|
|
45
64
|
}
|
|
65
|
+
/** Enable SIWE authentication using the default RPC URL as the auth endpoint. Auth is enabled by default; this is a no-op unless you previously called a method that disabled it. */
|
|
46
66
|
enableAuth() {
|
|
47
67
|
this._authEnabled = true;
|
|
48
68
|
return this;
|
|
49
69
|
}
|
|
70
|
+
/** Set a custom SIWE authentication endpoint and enable auth. */
|
|
50
71
|
authUrl(value) {
|
|
51
72
|
this._authUrl = value;
|
|
52
73
|
this._authEnabled = true;
|
|
53
74
|
return this;
|
|
54
75
|
}
|
|
76
|
+
/** Set the number of seconds before token expiry at which the session proactively refreshes. Enables auth. */
|
|
55
77
|
authRefreshMarginSecs(value) {
|
|
56
78
|
this._authRefreshMarginSecs = value;
|
|
57
79
|
this._authEnabled = true;
|
|
58
80
|
return this;
|
|
59
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Load configuration from environment variables.
|
|
84
|
+
*
|
|
85
|
+
* Recognised variables:
|
|
86
|
+
* - `4MICA_RPC_URL`
|
|
87
|
+
* - `4MICA_WALLET_PRIVATE_KEY`
|
|
88
|
+
* - `4MICA_ETHEREUM_HTTP_RPC_URL`
|
|
89
|
+
* - `4MICA_CONTRACT_ADDRESS`
|
|
90
|
+
* - `4MICA_ADMIN_API_KEY`
|
|
91
|
+
* - `4MICA_BEARER_TOKEN`
|
|
92
|
+
* - `4MICA_AUTH_URL`
|
|
93
|
+
* - `4MICA_AUTH_REFRESH_MARGIN_SECS`
|
|
94
|
+
*/
|
|
60
95
|
fromEnv() {
|
|
61
96
|
const env = process.env;
|
|
62
97
|
if (env['4MICA_RPC_URL'])
|
|
@@ -81,6 +116,12 @@ class ConfigBuilder {
|
|
|
81
116
|
}
|
|
82
117
|
return this;
|
|
83
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate all settings and return an immutable {@link Config}.
|
|
121
|
+
*
|
|
122
|
+
* @throws {@link ConfigError} if required fields are missing, URLs are invalid,
|
|
123
|
+
* or the auth refresh margin is not a finite non-negative number.
|
|
124
|
+
*/
|
|
84
125
|
build() {
|
|
85
126
|
if (!this._signer && !this._walletPrivateKey) {
|
|
86
127
|
throw new errors_1.ConfigError('missing signer or wallet_private_key');
|