@4mica/sdk 1.2.13 → 1.2.14
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 +7 -0
- package/dist/package.json +6 -2
- package/dist/src/client/user.d.ts +18 -4
- package/dist/src/client/user.js +30 -10
- package/dist/src/contract.js +5 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/wallet/cdp.d.ts +11 -0
- package/dist/src/wallet/cdp.js +85 -0
- package/dist/src/wallet/index.d.ts +2 -0
- package/dist/src/wallet/index.js +5 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -316,6 +316,13 @@ Notes:
|
|
|
316
316
|
- `cancelWithdrawal(erc20Token?)`
|
|
317
317
|
- `finalizeWithdrawal(erc20Token?)`
|
|
318
318
|
|
|
319
|
+
ERC20 approval behavior:
|
|
320
|
+
|
|
321
|
+
- `deposit(amount, erc20Token)` requires a prior `approveErc20(token, amount)` call.
|
|
322
|
+
- `payTab(...)` auto-approves the Core4Mica contract when paying an ERC20 tab and the current
|
|
323
|
+
allowance is below the payment amount.
|
|
324
|
+
- `approveErc20` returns `undefined` when the existing allowance is already sufficient.
|
|
325
|
+
|
|
319
326
|
#### RecipientClient Methods
|
|
320
327
|
|
|
321
328
|
- `createTab(userAddress, recipientAddress, erc20Token?, ttl?, guaranteeVersion?)`
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4mica/sdk",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.14",
|
|
4
4
|
"description": "TypeScript SDK for interacting with the 4Mica payment network",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -56,8 +56,12 @@
|
|
|
56
56
|
"@quillai-network/wachai-validation-sdk": "^0.1.0",
|
|
57
57
|
"viem": "^2.45.1"
|
|
58
58
|
},
|
|
59
|
+
"optionalDependencies": {
|
|
60
|
+
"@coinbase/cdp-sdk": "^1.49.2"
|
|
61
|
+
},
|
|
59
62
|
"devDependencies": {
|
|
60
|
-
"@4mica/x402": "^1.2.
|
|
63
|
+
"@4mica/x402": "^1.2.5",
|
|
64
|
+
"@coinbase/cdp-sdk": "^1.49.2",
|
|
61
65
|
"@eslint/js": "^9.39.2",
|
|
62
66
|
"@types/node": "^25.2.0",
|
|
63
67
|
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PaymentGuaranteeRequestClaims, PaymentGuaranteeRequestClaimsV2, PaymentSignature, SigningScheme, TabPaymentStatus, UserInfo } from '../models';
|
|
1
|
+
import { PaymentGuaranteeRequestClaims, PaymentGuaranteeRequestClaimsV2, PaymentSignature, SigningScheme, TabInfo, TabPaymentStatus, UserInfo } from '../models';
|
|
2
2
|
import type { TxReceiptWaitOptions } from '../contract';
|
|
3
3
|
import type { Client } from './index';
|
|
4
4
|
/** Payer-side operations: collateral management, payment signing, withdrawals. */
|
|
@@ -57,9 +57,23 @@ export declare class UserClient {
|
|
|
57
57
|
*/
|
|
58
58
|
signPayment(claims: PaymentGuaranteeRequestClaims | PaymentGuaranteeRequestClaimsV2, scheme?: SigningScheme): Promise<PaymentSignature>;
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
60
|
+
* List all tabs where the current signer is the payer.
|
|
61
61
|
*
|
|
62
|
-
*
|
|
62
|
+
* @param recipientAddress - Address of the recipient to query tabs from.
|
|
63
|
+
* @returns Array of tabs belonging to the current signer.
|
|
64
|
+
*/
|
|
65
|
+
listTabs(recipientAddress: string): Promise<TabInfo[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Pay a tab on-chain. Automatically resolves the recipient, asset, and amount
|
|
68
|
+
* from the tab and its latest guarantee.
|
|
69
|
+
*
|
|
70
|
+
* @param tabId - Tab identifier.
|
|
71
|
+
* @param waitOptions - Optional timeout/polling overrides.
|
|
72
|
+
* @throws if the tab is not found or has no guarantee.
|
|
73
|
+
*/
|
|
74
|
+
payTab(tabId: number | bigint, waitOptions?: TxReceiptWaitOptions): Promise<unknown>;
|
|
75
|
+
/**
|
|
76
|
+
* Pay a tab on-chain with explicit parameters.
|
|
63
77
|
*
|
|
64
78
|
* @param tabId - Tab identifier.
|
|
65
79
|
* @param reqId - Request ID from the latest guarantee (used for ETH payment memo).
|
|
@@ -68,7 +82,7 @@ export declare class UserClient {
|
|
|
68
82
|
* @param erc20Token - ERC20 token address. Omit to pay in ETH.
|
|
69
83
|
* @param waitOptions - Optional timeout/polling overrides.
|
|
70
84
|
*/
|
|
71
|
-
payTab(tabId: number | bigint, reqId: number | bigint, amount: number | bigint | string, recipientAddress: string, erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<
|
|
85
|
+
payTab(tabId: number | bigint, reqId: number | bigint, amount: number | bigint | string, recipientAddress: string, erc20Token?: string, waitOptions?: TxReceiptWaitOptions): Promise<unknown>;
|
|
72
86
|
/**
|
|
73
87
|
* Initiate a collateral withdrawal request. The withdrawal is subject to an
|
|
74
88
|
* on-chain timelock before it can be finalised.
|
package/dist/src/client/user.js
CHANGED
|
@@ -79,18 +79,38 @@ class UserClient {
|
|
|
79
79
|
return this.client.signer.signRequest(this.client.params, claims, scheme);
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
82
|
+
* List all tabs where the current signer is the payer.
|
|
83
83
|
*
|
|
84
|
-
*
|
|
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.
|
|
84
|
+
* @param recipientAddress - Address of the recipient to query tabs from.
|
|
85
|
+
* @returns Array of tabs belonging to the current signer.
|
|
92
86
|
*/
|
|
93
|
-
async
|
|
87
|
+
async listTabs(recipientAddress) {
|
|
88
|
+
const myAddress = (0, utils_1.normalizeAddress)(this.client.signer.signer.address);
|
|
89
|
+
const raw = await this.client.rpc.listRecipientTabs(recipientAddress);
|
|
90
|
+
return raw
|
|
91
|
+
.map((t) => models_1.TabInfo.fromRpc(t))
|
|
92
|
+
.filter((t) => (0, utils_1.normalizeAddress)(t.userAddress) === myAddress);
|
|
93
|
+
}
|
|
94
|
+
async payTab(tabId, reqIdOrWaitOptions, amount, recipientAddress, erc20Token, waitOptions) {
|
|
95
|
+
// Simple overload: auto-resolve from tab + latest guarantee
|
|
96
|
+
if (reqIdOrWaitOptions === undefined ||
|
|
97
|
+
(typeof reqIdOrWaitOptions === 'object' &&
|
|
98
|
+
reqIdOrWaitOptions !== null &&
|
|
99
|
+
!('valueOf' in reqIdOrWaitOptions && typeof reqIdOrWaitOptions.valueOf() === 'bigint'))) {
|
|
100
|
+
const opts = reqIdOrWaitOptions;
|
|
101
|
+
const tab = await this.client.recipient.getTab(tabId);
|
|
102
|
+
if (!tab)
|
|
103
|
+
throw new Error(`Tab ${tabId} not found`);
|
|
104
|
+
const guarantee = await this.client.recipient.getLatestGuarantee(tabId);
|
|
105
|
+
if (!guarantee)
|
|
106
|
+
throw new Error(`Tab ${tabId} has no guarantee`);
|
|
107
|
+
const isEth = tab.assetAddress === '0x0000000000000000000000000000000000000000';
|
|
108
|
+
return isEth
|
|
109
|
+
? this.client.gateway.payTabEth(tabId, guarantee.reqId, guarantee.amount, tab.recipientAddress, opts)
|
|
110
|
+
: this.client.gateway.payTabErc20(tabId, guarantee.amount, tab.assetAddress, tab.recipientAddress, opts);
|
|
111
|
+
}
|
|
112
|
+
// Explicit overload
|
|
113
|
+
const reqId = reqIdOrWaitOptions;
|
|
94
114
|
if (erc20Token) {
|
|
95
115
|
return this.client.gateway.payTabErc20(tabId, amount, erc20Token, recipientAddress, waitOptions);
|
|
96
116
|
}
|
package/dist/src/contract.js
CHANGED
|
@@ -246,7 +246,11 @@ class ContractGateway {
|
|
|
246
246
|
}
|
|
247
247
|
async payTabErc20(tabId, amount, erc20Token, recipient, waitOptions) {
|
|
248
248
|
const { gas, receipt } = this.splitWaitOptions(waitOptions);
|
|
249
|
-
const
|
|
249
|
+
const parsedAmount = (0, utils_1.parseU256)(amount);
|
|
250
|
+
// payTabInERC20Token uses safeTransferFrom, so the contract must be an
|
|
251
|
+
// approved spender. Auto-approve if the current allowance is insufficient.
|
|
252
|
+
await this.approveErc20(erc20Token, parsedAmount, waitOptions);
|
|
253
|
+
const hash = await this.enqueueTx(() => this.contract.write.payTabInERC20Token([(0, utils_1.parseU256)(tabId), erc20Token, parsedAmount, recipient], {
|
|
250
254
|
gas: gas ?? DEFAULT_PAY_TAB_ERC20_GAS_LIMIT,
|
|
251
255
|
...this.defaultFeeParams(),
|
|
252
256
|
}));
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Account } from 'viem';
|
|
2
|
+
export interface CdpAccountConfig {
|
|
3
|
+
/** CDP API key ID from the Coinbase Developer Platform dashboard. */
|
|
4
|
+
apiKeyId: string;
|
|
5
|
+
/** CDP API key secret from the Coinbase Developer Platform dashboard. */
|
|
6
|
+
apiKeySecret: string;
|
|
7
|
+
/** Idempotency name — getOrCreateAccount always returns the same wallet for a given name. */
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
/** Creates a viem Account backed by a Coinbase CDP MPC wallet (private key never leaves CDP). */
|
|
11
|
+
export declare function createCdpAccount(config: CdpAccountConfig): Promise<Account>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createCdpAccount = createCdpAccount;
|
|
37
|
+
const viem_1 = require("viem");
|
|
38
|
+
const accounts_1 = require("viem/accounts");
|
|
39
|
+
/** Creates a viem Account backed by a Coinbase CDP MPC wallet (private key never leaves CDP). */
|
|
40
|
+
async function createCdpAccount(config) {
|
|
41
|
+
const { CdpClient } = await Promise.resolve().then(() => __importStar(require('@coinbase/cdp-sdk')));
|
|
42
|
+
const cdp = new CdpClient({
|
|
43
|
+
apiKeyId: config.apiKeyId,
|
|
44
|
+
apiKeySecret: config.apiKeySecret,
|
|
45
|
+
});
|
|
46
|
+
const evmAccount = await cdp.evm.getOrCreateAccount({ name: config.name });
|
|
47
|
+
const address = evmAccount.address;
|
|
48
|
+
async function signMessage({ message }) {
|
|
49
|
+
if (typeof message === 'string') {
|
|
50
|
+
// CDP's signMessage applies the EIP-191 prefix internally.
|
|
51
|
+
const result = await cdp.evm.signMessage({ address, message });
|
|
52
|
+
return result.signature;
|
|
53
|
+
}
|
|
54
|
+
const hash = (0, viem_1.hashMessage)(message);
|
|
55
|
+
const result = await cdp.evm.signHash({ address, hash });
|
|
56
|
+
return result.signature;
|
|
57
|
+
}
|
|
58
|
+
async function signTypedData(parameters) {
|
|
59
|
+
const { domain, types, primaryType, message } = parameters;
|
|
60
|
+
if (domain && types && primaryType && message) {
|
|
61
|
+
try {
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
const payload = { address, domain, types, primaryType, message };
|
|
64
|
+
const result = await cdp.evm.signTypedData(payload);
|
|
65
|
+
return result.signature;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Fall back to hash-then-sign if CDP rejects the typed-data structure.
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const hash = (0, viem_1.hashTypedData)(parameters);
|
|
72
|
+
const result = await cdp.evm.signHash({ address, hash });
|
|
73
|
+
return result.signature;
|
|
74
|
+
}
|
|
75
|
+
async function signTransaction(transaction, options) {
|
|
76
|
+
const serializer = options?.serializer ?? viem_1.serializeTransaction;
|
|
77
|
+
const hash = (0, viem_1.keccak256)(serializer(transaction));
|
|
78
|
+
const result = await cdp.evm.signHash({ address, hash });
|
|
79
|
+
const { r, s, yParity } = (0, viem_1.hexToSignature)(result.signature);
|
|
80
|
+
return serializer(transaction, { r, s, yParity });
|
|
81
|
+
}
|
|
82
|
+
// viem's signTypedData generic cannot be satisfied by a hand-rolled adapter without casting — same pattern as hdKeyToAccount.
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
return (0, accounts_1.toAccount)({ address, signMessage, signTypedData, signTransaction });
|
|
85
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCdpAccount = void 0;
|
|
4
|
+
var cdp_1 = require("./cdp");
|
|
5
|
+
Object.defineProperty(exports, "createCdpAccount", { enumerable: true, get: function () { return cdp_1.createCdpAccount; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4mica/sdk",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.14",
|
|
4
4
|
"description": "TypeScript SDK for interacting with the 4Mica payment network",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -56,8 +56,12 @@
|
|
|
56
56
|
"@quillai-network/wachai-validation-sdk": "^0.1.0",
|
|
57
57
|
"viem": "^2.45.1"
|
|
58
58
|
},
|
|
59
|
+
"optionalDependencies": {
|
|
60
|
+
"@coinbase/cdp-sdk": "^1.49.2"
|
|
61
|
+
},
|
|
59
62
|
"devDependencies": {
|
|
60
|
-
"@4mica/x402": "^1.2.
|
|
63
|
+
"@4mica/x402": "^1.2.5",
|
|
64
|
+
"@coinbase/cdp-sdk": "^1.49.2",
|
|
61
65
|
"@eslint/js": "^9.39.2",
|
|
62
66
|
"@types/node": "^25.2.0",
|
|
63
67
|
"@typescript-eslint/eslint-plugin": "^8.54.0",
|