@4mica/sdk 1.0.0 → 1.0.2
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 +17 -0
- package/dist/contract.d.ts +1 -0
- package/dist/contract.js +44 -18
- package/package.json +7 -2
- package/dist/abi/core4mica.json +0 -1605
- package/dist/abi/erc20.json +0 -187
- package/dist/client.d.ts +0 -56
- package/dist/client.js +0 -258
- package/dist/src/abi/core4mica.json +0 -1605
- package/dist/src/abi/erc20.json +0 -187
- package/dist/src/bls.d.ts +0 -5
- package/dist/src/bls.js +0 -45
- package/dist/src/client.d.ts +0 -55
- package/dist/src/client.js +0 -214
- package/dist/src/config.d.ts +0 -21
- package/dist/src/config.js +0 -76
- package/dist/src/contract.d.ts +0 -33
- package/dist/src/contract.js +0 -121
- package/dist/src/errors.d.ts +0 -17
- package/dist/src/errors.js +0 -31
- package/dist/src/guarantee.d.ts +0 -3
- package/dist/src/guarantee.js +0 -66
- package/dist/src/index.d.ts +0 -11
- package/dist/src/index.js +0 -27
- package/dist/src/models.d.ts +0 -119
- package/dist/src/models.js +0 -132
- package/dist/src/rpc.d.ts +0 -30
- package/dist/src/rpc.js +0 -122
- package/dist/src/signing.d.ts +0 -16
- package/dist/src/signing.js +0 -102
- package/dist/src/utils.d.ts +0 -8
- package/dist/src/utils.js +0 -78
- package/dist/src/x402.d.ts +0 -77
- package/dist/src/x402.js +0 -214
- package/dist/tests/config.test.d.ts +0 -1
- package/dist/tests/config.test.js +0 -26
- package/dist/tests/guarantee.test.d.ts +0 -1
- package/dist/tests/guarantee.test.js +0 -26
- package/dist/tests/rpc.test.d.ts +0 -1
- package/dist/tests/rpc.test.js +0 -44
- package/dist/tests/signing.test.d.ts +0 -1
- package/dist/tests/signing.test.js +0 -25
- package/dist/tests/utils.test.d.ts +0 -1
- package/dist/tests/utils.test.js +0 -25
- package/dist/tests/x402.test.d.ts +0 -1
- package/dist/tests/x402.test.js +0 -65
- package/dist/x402.d.ts +0 -78
- package/dist/x402.js +0 -231
package/README.md
CHANGED
|
@@ -144,6 +144,23 @@ The SDK exposes three main entry points:
|
|
|
144
144
|
- `client.recipient`: recipient-side operations (tabs, guarantees, remuneration)
|
|
145
145
|
- `X402Flow`: helper for 402-protected HTTP resources
|
|
146
146
|
|
|
147
|
+
### End-to-end Example (Base Sepolia + x402 v2)
|
|
148
|
+
|
|
149
|
+
See `examples/base-sepolia-x402-facilitator-e2e.ts` for a full flow in the `examples` folder:
|
|
150
|
+
- deposit collateral
|
|
151
|
+
- create/get a tab via facilitator
|
|
152
|
+
- issue and verify V1 + V2 guarantees
|
|
153
|
+
- `payTab` in ERC20 for V1
|
|
154
|
+
- remunerate V2 only after `wachai-validation-sdk` returns a passing ERC-8004 validation
|
|
155
|
+
- submit + finalize withdrawal
|
|
156
|
+
|
|
157
|
+
Run it with:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
cp examples/.env.x402-facilitator-e2e.example examples/.env.x402-facilitator-e2e
|
|
161
|
+
npx dotenv-cli -e examples/.env.x402-facilitator-e2e -- npm run example:base-sepolia:x402-v2
|
|
162
|
+
```
|
|
163
|
+
|
|
147
164
|
### X402 flow (HTTP 402)
|
|
148
165
|
|
|
149
166
|
The X402 helper turns `paymentRequirements` from a `402 Payment Required` response into an
|
package/dist/contract.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare class ContractGateway {
|
|
|
21
21
|
static create(rpcUrl: string, signer: Account, contractAddress: Hex, chainId: number): Promise<ContractGateway>;
|
|
22
22
|
private erc20;
|
|
23
23
|
private enqueueTx;
|
|
24
|
+
private defaultFeeParams;
|
|
24
25
|
private splitWaitOptions;
|
|
25
26
|
getGuaranteeDomain(): Promise<string>;
|
|
26
27
|
getGuaranteeVersionConfig(version: number): Promise<{
|
package/dist/contract.js
CHANGED
|
@@ -7,6 +7,9 @@ const chain_1 = require("./chain");
|
|
|
7
7
|
const errors_1 = require("./errors");
|
|
8
8
|
const utils_1 = require("./utils");
|
|
9
9
|
const DEFAULT_REMUNERATE_GAS_LIMIT = 8000000n;
|
|
10
|
+
const DEFAULT_PAY_TAB_ERC20_GAS_LIMIT = 300000n;
|
|
11
|
+
const DEFAULT_MAX_FEE_PER_GAS = (0, viem_1.parseGwei)('0.1');
|
|
12
|
+
const DEFAULT_MAX_PRIORITY_FEE_PER_GAS = (0, viem_1.parseGwei)('0.1');
|
|
10
13
|
class ContractGateway {
|
|
11
14
|
publicClient;
|
|
12
15
|
walletClient;
|
|
@@ -58,6 +61,12 @@ class ContractGateway {
|
|
|
58
61
|
this.txQueue = run.then(() => undefined, () => undefined);
|
|
59
62
|
return run;
|
|
60
63
|
}
|
|
64
|
+
defaultFeeParams() {
|
|
65
|
+
return {
|
|
66
|
+
maxFeePerGas: DEFAULT_MAX_FEE_PER_GAS,
|
|
67
|
+
maxPriorityFeePerGas: DEFAULT_MAX_PRIORITY_FEE_PER_GAS,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
61
70
|
splitWaitOptions(waitOptions) {
|
|
62
71
|
if (!waitOptions) {
|
|
63
72
|
return { receipt: {} };
|
|
@@ -81,19 +90,36 @@ class ContractGateway {
|
|
|
81
90
|
async approveErc20(token, amount, waitOptions) {
|
|
82
91
|
const { receipt } = this.splitWaitOptions(waitOptions);
|
|
83
92
|
const erc20 = this.erc20(token);
|
|
84
|
-
// spender address logic
|
|
85
93
|
const spender = this.contract.address;
|
|
86
|
-
const
|
|
87
|
-
|
|
94
|
+
const targetAllowance = (0, utils_1.parseU256)(amount);
|
|
95
|
+
const sendApprove = async (value) => {
|
|
96
|
+
const hash = await this.enqueueTx(() => erc20.write.approve([spender, value], this.defaultFeeParams()));
|
|
97
|
+
const txReceipt = await this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
98
|
+
if (txReceipt.status !== 'success') {
|
|
99
|
+
throw new errors_1.ContractError(`approve transaction reverted: ${hash}`);
|
|
100
|
+
}
|
|
101
|
+
return txReceipt;
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
return await sendApprove(targetAllowance);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// Some ERC20s require resetting allowance to zero before setting a new value.
|
|
108
|
+
if (targetAllowance === 0n) {
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
await sendApprove(0n);
|
|
112
|
+
return sendApprove(targetAllowance);
|
|
113
|
+
}
|
|
88
114
|
}
|
|
89
115
|
async deposit(amount, erc20Token, waitOptions) {
|
|
90
116
|
const { receipt } = this.splitWaitOptions(waitOptions);
|
|
91
117
|
let hash;
|
|
92
118
|
if (erc20Token) {
|
|
93
|
-
hash = await this.enqueueTx(() => this.contract.write.depositStablecoin([erc20Token, (0, utils_1.parseU256)(amount)]));
|
|
119
|
+
hash = await this.enqueueTx(() => this.contract.write.depositStablecoin([erc20Token, (0, utils_1.parseU256)(amount)], this.defaultFeeParams()));
|
|
94
120
|
}
|
|
95
121
|
else {
|
|
96
|
-
hash = await this.enqueueTx(() => this.contract.write.deposit({ value: (0, utils_1.parseU256)(amount) }));
|
|
122
|
+
hash = await this.enqueueTx(() => this.contract.write.deposit({ value: (0, utils_1.parseU256)(amount), ...this.defaultFeeParams() }));
|
|
97
123
|
}
|
|
98
124
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
99
125
|
}
|
|
@@ -128,17 +154,16 @@ class ContractGateway {
|
|
|
128
154
|
to: recipient,
|
|
129
155
|
value: (0, utils_1.parseU256)(amount),
|
|
130
156
|
data: (0, utils_1.hexFromBytes)(data),
|
|
157
|
+
...this.defaultFeeParams(),
|
|
131
158
|
}));
|
|
132
159
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
133
160
|
}
|
|
134
161
|
async payTabErc20(tabId, amount, erc20Token, recipient, waitOptions) {
|
|
135
|
-
const { receipt } = this.splitWaitOptions(waitOptions);
|
|
136
|
-
const hash = await this.enqueueTx(() => this.contract.write.payTabInERC20Token([
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
recipient,
|
|
141
|
-
]));
|
|
162
|
+
const { gas, receipt } = this.splitWaitOptions(waitOptions);
|
|
163
|
+
const hash = await this.enqueueTx(() => this.contract.write.payTabInERC20Token([(0, utils_1.parseU256)(tabId), erc20Token, (0, utils_1.parseU256)(amount), recipient], {
|
|
164
|
+
gas: gas ?? DEFAULT_PAY_TAB_ERC20_GAS_LIMIT,
|
|
165
|
+
...this.defaultFeeParams(),
|
|
166
|
+
}));
|
|
142
167
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
143
168
|
}
|
|
144
169
|
async requestWithdrawal(amount, erc20Token, waitOptions) {
|
|
@@ -146,10 +171,10 @@ class ContractGateway {
|
|
|
146
171
|
const value = (0, utils_1.parseU256)(amount);
|
|
147
172
|
let hash;
|
|
148
173
|
if (erc20Token) {
|
|
149
|
-
hash = await this.enqueueTx(() => this.contract.write.requestWithdrawal([erc20Token, value]));
|
|
174
|
+
hash = await this.enqueueTx(() => this.contract.write.requestWithdrawal([erc20Token, value], this.defaultFeeParams()));
|
|
150
175
|
}
|
|
151
176
|
else {
|
|
152
|
-
hash = await this.enqueueTx(() => this.contract.write.requestWithdrawal([value]));
|
|
177
|
+
hash = await this.enqueueTx(() => this.contract.write.requestWithdrawal([value], this.defaultFeeParams()));
|
|
153
178
|
}
|
|
154
179
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
155
180
|
}
|
|
@@ -157,10 +182,10 @@ class ContractGateway {
|
|
|
157
182
|
const { receipt } = this.splitWaitOptions(waitOptions);
|
|
158
183
|
let hash;
|
|
159
184
|
if (erc20Token) {
|
|
160
|
-
hash = await this.enqueueTx(() => this.contract.write.cancelWithdrawal([erc20Token]));
|
|
185
|
+
hash = await this.enqueueTx(() => this.contract.write.cancelWithdrawal([erc20Token], this.defaultFeeParams()));
|
|
161
186
|
}
|
|
162
187
|
else {
|
|
163
|
-
hash = await this.enqueueTx(() => this.contract.write.cancelWithdrawal());
|
|
188
|
+
hash = await this.enqueueTx(() => this.contract.write.cancelWithdrawal(this.defaultFeeParams()));
|
|
164
189
|
}
|
|
165
190
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
166
191
|
}
|
|
@@ -168,10 +193,10 @@ class ContractGateway {
|
|
|
168
193
|
const { receipt } = this.splitWaitOptions(waitOptions);
|
|
169
194
|
let hash;
|
|
170
195
|
if (erc20Token) {
|
|
171
|
-
hash = await this.enqueueTx(() => this.contract.write.finalizeWithdrawal([erc20Token]));
|
|
196
|
+
hash = await this.enqueueTx(() => this.contract.write.finalizeWithdrawal([erc20Token], this.defaultFeeParams()));
|
|
172
197
|
}
|
|
173
198
|
else {
|
|
174
|
-
hash = await this.enqueueTx(() => this.contract.write.finalizeWithdrawal());
|
|
199
|
+
hash = await this.enqueueTx(() => this.contract.write.finalizeWithdrawal(this.defaultFeeParams()));
|
|
175
200
|
}
|
|
176
201
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
177
202
|
}
|
|
@@ -189,6 +214,7 @@ class ContractGateway {
|
|
|
189
214
|
};
|
|
190
215
|
const hash = await this.enqueueTx(() => this.contract.write.remunerate([(0, utils_1.hexFromBytes)(claimsBlob), sigStruct], {
|
|
191
216
|
gas: gas ?? DEFAULT_REMUNERATE_GAS_LIMIT,
|
|
217
|
+
...this.defaultFeeParams(),
|
|
192
218
|
}));
|
|
193
219
|
return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
|
|
194
220
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4mica/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "TypeScript SDK for interacting with the 4Mica payment network",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,14 +39,19 @@
|
|
|
39
39
|
"ethers"
|
|
40
40
|
],
|
|
41
41
|
"scripts": {
|
|
42
|
-
"
|
|
42
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{ recursive: true, force: true })\"",
|
|
43
|
+
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
43
44
|
"test": "vitest run",
|
|
44
45
|
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
46
|
+
"example:base-sepolia:x402-v2": "node_modules/.bin/tsx examples/base-sepolia-x402-facilitator-e2e.ts",
|
|
47
|
+
"example:manual:agents": "node_modules/.bin/tsx examples/manual-agents/demo.ts",
|
|
45
48
|
"lint": "eslint . --ext .ts",
|
|
46
49
|
"fmt": "prettier --check \"{src,tests}/**/*.{ts,js,json}\""
|
|
47
50
|
},
|
|
48
51
|
"dependencies": {
|
|
52
|
+
"@4mica/x402": "file:../x402-4mica/packages/typescript/x402",
|
|
49
53
|
"@noble/curves": "^2.0.1",
|
|
54
|
+
"@quillai-network/wachai-validation-sdk": "^0.1.0",
|
|
50
55
|
"viem": "^2.45.1"
|
|
51
56
|
},
|
|
52
57
|
"devDependencies": {
|