@magnaflow/contract-sdk 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 +64 -0
- package/dist/contract-caller.d.ts +25 -0
- package/dist/contract-caller.d.ts.map +1 -0
- package/dist/contract-caller.js +30 -0
- package/dist/contract-manager.d.ts +29 -0
- package/dist/contract-manager.d.ts.map +1 -0
- package/dist/contract-manager.js +101 -0
- package/dist/eip712-signer.d.ts +7 -0
- package/dist/eip712-signer.d.ts.map +1 -0
- package/dist/eip712-signer.js +20 -0
- package/dist/erc20-abi.d.ts +59 -0
- package/dist/erc20-abi.d.ts.map +1 -0
- package/dist/erc20-abi.js +39 -0
- package/dist/error-handler.d.ts +33 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +123 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/payout-abi.d.ts +811 -0
- package/dist/payout-abi.d.ts.map +1 -0
- package/dist/payout-abi.js +675 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# @magnaflow/contract-sdk
|
|
2
|
+
|
|
3
|
+
Contract call helpers built on top of `@magnaflow/chain-provider`.
|
|
4
|
+
|
|
5
|
+
## What It Provides
|
|
6
|
+
|
|
7
|
+
- `ContractManager` for low-level read, write, and gas estimation
|
|
8
|
+
- `ContractCaller` as a thin convenience wrapper
|
|
9
|
+
- EIP-712 digest signing with `signDigest`
|
|
10
|
+
- Standard MagnaFlow error selector parsing
|
|
11
|
+
- Bundled ABIs for payout and ERC-20 flows
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @magnaflow/contract-sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Key Exports
|
|
20
|
+
|
|
21
|
+
- `ContractManager`
|
|
22
|
+
- `ContractCaller`
|
|
23
|
+
- `signDigest`
|
|
24
|
+
- `parseEvmError`
|
|
25
|
+
- `parseContractError`
|
|
26
|
+
- `createFriendlyErrorMessage`
|
|
27
|
+
- `MAGNAFLOW_ERROR_SELECTORS`
|
|
28
|
+
- `payout_new_abi`
|
|
29
|
+
- `ORDER_STRUCT_TYPE`
|
|
30
|
+
- `ERC20_ABI`
|
|
31
|
+
|
|
32
|
+
## Example
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { ContractCaller, ERC20_ABI } from '@magnaflow/contract-sdk';
|
|
36
|
+
import { createChainProvider } from '@magnaflow/chain-provider';
|
|
37
|
+
|
|
38
|
+
const provider = createChainProvider(chainConfig, process.env.MNEMONIC);
|
|
39
|
+
const caller = new ContractCaller(provider);
|
|
40
|
+
|
|
41
|
+
const balance = await caller.call({
|
|
42
|
+
address: '0x55d398326f99059fF775485246999027B3197955',
|
|
43
|
+
abi: ERC20_ABI,
|
|
44
|
+
functionName: 'balanceOf',
|
|
45
|
+
args: ['0x1234...'],
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Notes
|
|
50
|
+
|
|
51
|
+
- EVM contract read/write is implemented.
|
|
52
|
+
- Tron contract read/write is not implemented in the current release and should be treated as unsupported.
|
|
53
|
+
|
|
54
|
+
## Development
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bunx nx run contract-sdk:lint
|
|
58
|
+
bunx nx run contract-sdk:test
|
|
59
|
+
bunx nx run contract-sdk:build
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract caller for simplified contract interactions
|
|
3
|
+
*/
|
|
4
|
+
import type { ChainProvider } from '@magnaflow/chain-provider';
|
|
5
|
+
import type { ContractCallParams, ContractWriteParams } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Contract caller utility
|
|
8
|
+
*/
|
|
9
|
+
export declare class ContractCaller {
|
|
10
|
+
private contractManager;
|
|
11
|
+
constructor(provider: ChainProvider);
|
|
12
|
+
/**
|
|
13
|
+
* Call contract view function
|
|
14
|
+
*/
|
|
15
|
+
call<T = unknown>(params: ContractCallParams): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Send contract transaction
|
|
18
|
+
*/
|
|
19
|
+
send(params: ContractWriteParams): Promise<import("./types").ContractTransactionResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Estimate gas for contract call
|
|
22
|
+
*/
|
|
23
|
+
estimateGas(params: ContractCallParams): Promise<bigint>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=contract-caller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-caller.d.ts","sourceRoot":"","sources":["../src/contract-caller.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEvE;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAAkB;gBAE7B,QAAQ,EAAE,aAAa;IAInC;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/D;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,mBAAmB;IAItC;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;CAG/D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract caller for simplified contract interactions
|
|
3
|
+
*/
|
|
4
|
+
import { ContractManager } from './contract-manager';
|
|
5
|
+
/**
|
|
6
|
+
* Contract caller utility
|
|
7
|
+
*/
|
|
8
|
+
export class ContractCaller {
|
|
9
|
+
constructor(provider) {
|
|
10
|
+
this.contractManager = new ContractManager(provider);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Call contract view function
|
|
14
|
+
*/
|
|
15
|
+
async call(params) {
|
|
16
|
+
return await this.contractManager.readContract(params);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Send contract transaction
|
|
20
|
+
*/
|
|
21
|
+
async send(params) {
|
|
22
|
+
return await this.contractManager.writeContract(params);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Estimate gas for contract call
|
|
26
|
+
*/
|
|
27
|
+
async estimateGas(params) {
|
|
28
|
+
return await this.contractManager.estimateContractGas(params);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract manager for unified contract interactions
|
|
3
|
+
*/
|
|
4
|
+
import type { ChainProvider } from '@magnaflow/chain-provider';
|
|
5
|
+
import type { ContractCallParams, ContractWriteParams, ContractTransactionResult } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Contract manager
|
|
8
|
+
*/
|
|
9
|
+
export declare class ContractManager {
|
|
10
|
+
private provider;
|
|
11
|
+
constructor(provider: ChainProvider);
|
|
12
|
+
/**
|
|
13
|
+
* Read from contract
|
|
14
|
+
*/
|
|
15
|
+
readContract<T = unknown>(params: ContractCallParams): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Write to contract
|
|
18
|
+
*/
|
|
19
|
+
writeContract(params: ContractWriteParams): Promise<ContractTransactionResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Estimate gas for contract call
|
|
22
|
+
*/
|
|
23
|
+
estimateContractGas(params: ContractCallParams): Promise<bigint>;
|
|
24
|
+
/**
|
|
25
|
+
* Get contract instance (for advanced usage)
|
|
26
|
+
*/
|
|
27
|
+
getProvider(): ChainProvider;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=contract-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-manager.d.ts","sourceRoot":"","sources":["../src/contract-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAGlG;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAgB;gBAEpB,QAAQ,EAAE,aAAa;IAInC;;OAEG;IACG,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAiBvE;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA4CpF;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBtE;;OAEG;IACH,WAAW,IAAI,aAAa;CAG7B"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract manager for unified contract interactions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Contract manager
|
|
6
|
+
*/
|
|
7
|
+
export class ContractManager {
|
|
8
|
+
constructor(provider) {
|
|
9
|
+
this.provider = provider;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Read from contract
|
|
13
|
+
*/
|
|
14
|
+
async readContract(params) {
|
|
15
|
+
if (this.provider.getChainType() === 'evm') {
|
|
16
|
+
const evmProvider = this.provider;
|
|
17
|
+
const publicClient = evmProvider.getPublicClient();
|
|
18
|
+
return (await publicClient.readContract({
|
|
19
|
+
address: params.address,
|
|
20
|
+
abi: params.abi,
|
|
21
|
+
functionName: params.functionName,
|
|
22
|
+
args: params.args,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// Tron contract read
|
|
27
|
+
throw new Error('Tron contract read not yet implemented');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Write to contract
|
|
32
|
+
*/
|
|
33
|
+
async writeContract(params) {
|
|
34
|
+
if (this.provider.getChainType() === 'evm') {
|
|
35
|
+
const evmProvider = this.provider;
|
|
36
|
+
const walletClient = evmProvider.getWalletClient();
|
|
37
|
+
if (!walletClient) {
|
|
38
|
+
throw new Error('Wallet client not available');
|
|
39
|
+
}
|
|
40
|
+
const writeParams = {
|
|
41
|
+
address: params.address,
|
|
42
|
+
abi: params.abi,
|
|
43
|
+
functionName: params.functionName,
|
|
44
|
+
args: params.args,
|
|
45
|
+
};
|
|
46
|
+
if (params.value !== undefined) {
|
|
47
|
+
writeParams.value = params.value;
|
|
48
|
+
}
|
|
49
|
+
if (params.gasLimit !== undefined) {
|
|
50
|
+
writeParams.gas = params.gasLimit;
|
|
51
|
+
}
|
|
52
|
+
if (params.gasPrice !== undefined) {
|
|
53
|
+
writeParams.gasPrice = params.gasPrice;
|
|
54
|
+
}
|
|
55
|
+
if (params.maxFeePerGas !== undefined) {
|
|
56
|
+
writeParams.maxFeePerGas = params.maxFeePerGas;
|
|
57
|
+
}
|
|
58
|
+
if (params.maxPriorityFeePerGas !== undefined) {
|
|
59
|
+
writeParams.maxPriorityFeePerGas = params.maxPriorityFeePerGas;
|
|
60
|
+
}
|
|
61
|
+
const hash = await walletClient.writeContract(writeParams);
|
|
62
|
+
return {
|
|
63
|
+
hash,
|
|
64
|
+
chainType: 'evm',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// Tron contract write
|
|
69
|
+
throw new Error('Tron contract write not yet implemented');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Estimate gas for contract call
|
|
74
|
+
*/
|
|
75
|
+
async estimateContractGas(params) {
|
|
76
|
+
if (this.provider.getChainType() === 'evm') {
|
|
77
|
+
const evmProvider = this.provider;
|
|
78
|
+
const publicClient = evmProvider.getPublicClient();
|
|
79
|
+
const estimateParams = {
|
|
80
|
+
address: params.address,
|
|
81
|
+
abi: params.abi,
|
|
82
|
+
functionName: params.functionName,
|
|
83
|
+
args: params.args,
|
|
84
|
+
};
|
|
85
|
+
if (params.value !== undefined) {
|
|
86
|
+
estimateParams.value = params.value;
|
|
87
|
+
}
|
|
88
|
+
return await publicClient.estimateContractGas(estimateParams);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Tron doesn't have gas estimation
|
|
92
|
+
return BigInt(0);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get contract instance (for advanced usage)
|
|
97
|
+
*/
|
|
98
|
+
getProvider() {
|
|
99
|
+
return this.provider;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sign digest with private key
|
|
3
|
+
* Note: This is a placeholder. In practice, use viem's account signing
|
|
4
|
+
* or implement with @noble/secp256k1 for direct private key signing
|
|
5
|
+
*/
|
|
6
|
+
export declare function signDigest(digest: string, privateKey: string): Promise<`0x${string}`>;
|
|
7
|
+
//# sourceMappingURL=eip712-signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eip712-signer.d.ts","sourceRoot":"","sources":["../src/eip712-signer.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAc3F"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { sign } from 'viem/accounts';
|
|
2
|
+
import { bytesToHex, concatHex } from 'viem';
|
|
3
|
+
/**
|
|
4
|
+
* Sign digest with private key
|
|
5
|
+
* Note: This is a placeholder. In practice, use viem's account signing
|
|
6
|
+
* or implement with @noble/secp256k1 for direct private key signing
|
|
7
|
+
*/
|
|
8
|
+
export async function signDigest(digest, privateKey) {
|
|
9
|
+
const digestHex = digest.startsWith('0x') ? digest : `0x${digest}`;
|
|
10
|
+
const pk = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
|
|
11
|
+
const signature = await sign({
|
|
12
|
+
hash: digestHex,
|
|
13
|
+
privateKey: pk,
|
|
14
|
+
});
|
|
15
|
+
let v = Number(signature.v ?? 0);
|
|
16
|
+
if (v < 27) {
|
|
17
|
+
v = v + 27;
|
|
18
|
+
}
|
|
19
|
+
return concatHex([signature.r, signature.s, bytesToHex(Uint8Array.of(v))]);
|
|
20
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export declare const ERC20_ABI: readonly [{
|
|
2
|
+
readonly name: "balanceOf";
|
|
3
|
+
readonly type: "function";
|
|
4
|
+
readonly stateMutability: "view";
|
|
5
|
+
readonly inputs: readonly [{
|
|
6
|
+
readonly name: "owner";
|
|
7
|
+
readonly type: "address";
|
|
8
|
+
}];
|
|
9
|
+
readonly outputs: readonly [{
|
|
10
|
+
readonly name: "";
|
|
11
|
+
readonly type: "uint256";
|
|
12
|
+
}];
|
|
13
|
+
}, {
|
|
14
|
+
readonly name: "approve";
|
|
15
|
+
readonly type: "function";
|
|
16
|
+
readonly stateMutability: "nonpayable";
|
|
17
|
+
readonly inputs: readonly [{
|
|
18
|
+
readonly name: "spender";
|
|
19
|
+
readonly type: "address";
|
|
20
|
+
}, {
|
|
21
|
+
readonly name: "amount";
|
|
22
|
+
readonly type: "uint256";
|
|
23
|
+
}];
|
|
24
|
+
readonly outputs: readonly [{
|
|
25
|
+
readonly name: "";
|
|
26
|
+
readonly type: "bool";
|
|
27
|
+
}];
|
|
28
|
+
}, {
|
|
29
|
+
readonly name: "allowance";
|
|
30
|
+
readonly type: "function";
|
|
31
|
+
readonly stateMutability: "view";
|
|
32
|
+
readonly inputs: readonly [{
|
|
33
|
+
readonly name: "owner";
|
|
34
|
+
readonly type: "address";
|
|
35
|
+
}, {
|
|
36
|
+
readonly name: "spender";
|
|
37
|
+
readonly type: "address";
|
|
38
|
+
}];
|
|
39
|
+
readonly outputs: readonly [{
|
|
40
|
+
readonly name: "";
|
|
41
|
+
readonly type: "uint256";
|
|
42
|
+
}];
|
|
43
|
+
}, {
|
|
44
|
+
readonly name: "transfer";
|
|
45
|
+
readonly type: "function";
|
|
46
|
+
readonly stateMutability: "nonpayable";
|
|
47
|
+
readonly inputs: readonly [{
|
|
48
|
+
readonly name: "to";
|
|
49
|
+
readonly type: "address";
|
|
50
|
+
}, {
|
|
51
|
+
readonly name: "amount";
|
|
52
|
+
readonly type: "uint256";
|
|
53
|
+
}];
|
|
54
|
+
readonly outputs: readonly [{
|
|
55
|
+
readonly name: "";
|
|
56
|
+
readonly type: "bool";
|
|
57
|
+
}];
|
|
58
|
+
}];
|
|
59
|
+
//# sourceMappingURL=erc20-abi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erc20-abi.d.ts","sourceRoot":"","sources":["../src/erc20-abi.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCZ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const ERC20_ABI = [
|
|
2
|
+
{
|
|
3
|
+
name: 'balanceOf',
|
|
4
|
+
type: 'function',
|
|
5
|
+
stateMutability: 'view',
|
|
6
|
+
inputs: [{ name: 'owner', type: 'address' }],
|
|
7
|
+
outputs: [{ name: '', type: 'uint256' }],
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: 'approve',
|
|
11
|
+
type: 'function',
|
|
12
|
+
stateMutability: 'nonpayable',
|
|
13
|
+
inputs: [
|
|
14
|
+
{ name: 'spender', type: 'address' },
|
|
15
|
+
{ name: 'amount', type: 'uint256' },
|
|
16
|
+
],
|
|
17
|
+
outputs: [{ name: '', type: 'bool' }],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'allowance',
|
|
21
|
+
type: 'function',
|
|
22
|
+
stateMutability: 'view',
|
|
23
|
+
inputs: [
|
|
24
|
+
{ name: 'owner', type: 'address' },
|
|
25
|
+
{ name: 'spender', type: 'address' },
|
|
26
|
+
],
|
|
27
|
+
outputs: [{ name: '', type: 'uint256' }],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'transfer',
|
|
31
|
+
type: 'function',
|
|
32
|
+
stateMutability: 'nonpayable',
|
|
33
|
+
inputs: [
|
|
34
|
+
{ name: 'to', type: 'address' },
|
|
35
|
+
{ name: 'amount', type: 'uint256' },
|
|
36
|
+
],
|
|
37
|
+
outputs: [{ name: '', type: 'bool' }],
|
|
38
|
+
},
|
|
39
|
+
];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract error handler utilities
|
|
3
|
+
* Provides functions to parse and format contract errors
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* MagnaFlow contract error selector mapping
|
|
7
|
+
* Error selector = first 4 bytes of keccak256("ErrorName()")
|
|
8
|
+
*/
|
|
9
|
+
export declare const MAGNAFLOW_ERROR_SELECTORS: Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Parse error information from EVM contract error
|
|
12
|
+
* @param error - EVM error object (from ethers, viem, etc.)
|
|
13
|
+
* @param errorSelectors - Optional custom error selector mapping (defaults to MAGNAFLOW_ERROR_SELECTORS)
|
|
14
|
+
* @returns Parsed error message
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseEvmError(error: any, errorSelectors?: Record<string, string>): string;
|
|
17
|
+
/**
|
|
18
|
+
* Parse error information from contract result array
|
|
19
|
+
* Typically used for Tron contract errors or contract return values
|
|
20
|
+
* @param contractResult - The result array returned by the contract
|
|
21
|
+
* @param errorSelectors - Optional custom error selector mapping (defaults to MAGNAFLOW_ERROR_SELECTORS)
|
|
22
|
+
* @returns Parsed error information
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseContractError(contractResult: any[], errorSelectors?: Record<string, string>): string;
|
|
25
|
+
/**
|
|
26
|
+
* Create a friendly error message from an error object
|
|
27
|
+
* @param error - Original error object
|
|
28
|
+
* @param defaultMessage - Default error message (default: 'Operation failed')
|
|
29
|
+
* @param errorSelectors - Optional custom error selector mapping (defaults to MAGNAFLOW_ERROR_SELECTORS)
|
|
30
|
+
* @returns Friendly error message
|
|
31
|
+
*/
|
|
32
|
+
export declare function createFriendlyErrorMessage(error: any, defaultMessage?: string, errorSelectors?: Record<string, string>): string;
|
|
33
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAc5D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,GAAG,EACV,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAA6B,GACjE,MAAM,CAwDR;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,GAAG,EAAE,EACrB,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAA6B,GACjE,MAAM,CAsBR;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,GAAG,EACV,cAAc,GAAE,MAA2B,EAC3C,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAA6B,GACjE,MAAM,CAUR"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract error handler utilities
|
|
3
|
+
* Provides functions to parse and format contract errors
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* MagnaFlow contract error selector mapping
|
|
7
|
+
* Error selector = first 4 bytes of keccak256("ErrorName()")
|
|
8
|
+
*/
|
|
9
|
+
export const MAGNAFLOW_ERROR_SELECTORS = {
|
|
10
|
+
'0x7db491eb': 'InvalidInputLength - Input length mismatch (array length inconsistent or empty)',
|
|
11
|
+
'0x9c358fad': 'FundTransferFailed - Transfer failed (insufficient balance or allowance)',
|
|
12
|
+
'0xf4d678b8': 'InsufficientBalance - Insufficient balance',
|
|
13
|
+
'0x599989d2': 'InsufficientMerchantBalance - Insufficient merchant balance (cannot pay fee)',
|
|
14
|
+
'0x4b692736': 'InvalidEd25519PublicKey - Invalid Ed25519 public key',
|
|
15
|
+
'0x3a81d6fc': 'AlreadyRegistered - Already registered',
|
|
16
|
+
'0x8baa579f': 'InvalidSignature - Signature verification failed',
|
|
17
|
+
'0x56d69198': 'InvalidFeeRate - Invalid fee rate',
|
|
18
|
+
'0x2c5211c6': 'InvalidAmount - Invalid amount',
|
|
19
|
+
'0xe6f2de87': 'InvalidStableCoin - Not a stablecoin',
|
|
20
|
+
'0x9c8d2cd2': 'InvalidRecipient - Invalid recipient address',
|
|
21
|
+
'0xb89fe006': 'InvalidWhitelist - Not in whitelist',
|
|
22
|
+
'0xc0b6c919': 'InvalidMerchant - Invalid merchant address',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Parse error information from EVM contract error
|
|
26
|
+
* @param error - EVM error object (from ethers, viem, etc.)
|
|
27
|
+
* @param errorSelectors - Optional custom error selector mapping (defaults to MAGNAFLOW_ERROR_SELECTORS)
|
|
28
|
+
* @returns Parsed error message
|
|
29
|
+
*/
|
|
30
|
+
export function parseEvmError(error, errorSelectors = MAGNAFLOW_ERROR_SELECTORS) {
|
|
31
|
+
if (!error) {
|
|
32
|
+
return 'Unknown error';
|
|
33
|
+
}
|
|
34
|
+
// Try to extract error selector from error.data
|
|
35
|
+
let errorSelector = null;
|
|
36
|
+
// ethers v6 error format: error.data may be a string
|
|
37
|
+
if (error.data) {
|
|
38
|
+
if (typeof error.data === 'string') {
|
|
39
|
+
errorSelector = error.data;
|
|
40
|
+
}
|
|
41
|
+
else if (error.data.error?.data) {
|
|
42
|
+
// In some cases error data is in error.data.error.data
|
|
43
|
+
errorSelector = error.data.error.data;
|
|
44
|
+
}
|
|
45
|
+
else if (error.data.originalError?.data) {
|
|
46
|
+
// In some cases error data is in error.data.originalError.data
|
|
47
|
+
errorSelector = error.data.originalError.data;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// If error.data is a string, extract error selector (first 4 bytes = 10 characters)
|
|
51
|
+
if (errorSelector) {
|
|
52
|
+
// Ensure 0x prefix exists
|
|
53
|
+
let selector;
|
|
54
|
+
if (errorSelector.startsWith('0x')) {
|
|
55
|
+
// If length >= 10, take first 10 characters; otherwise use full string
|
|
56
|
+
selector = errorSelector.length >= 10 ? errorSelector.slice(0, 10) : errorSelector;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// If no 0x prefix, add it and take first 8 characters
|
|
60
|
+
selector = `0x${errorSelector.slice(0, 8)}`;
|
|
61
|
+
}
|
|
62
|
+
if (errorSelectors[selector]) {
|
|
63
|
+
return errorSelectors[selector];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Try to extract error selector from error message
|
|
67
|
+
if (error.message) {
|
|
68
|
+
// Look for pattern like "0x..." (8 hex characters)
|
|
69
|
+
const match = error.message.match(/0x[a-fA-F0-9]{8}/);
|
|
70
|
+
if (match) {
|
|
71
|
+
const selector = match[0];
|
|
72
|
+
if (errorSelectors[selector]) {
|
|
73
|
+
return errorSelectors[selector];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// If cannot parse, return original error message or default message
|
|
78
|
+
if (error.message) {
|
|
79
|
+
return error.message;
|
|
80
|
+
}
|
|
81
|
+
return 'Unknown error';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse error information from contract result array
|
|
85
|
+
* Typically used for Tron contract errors or contract return values
|
|
86
|
+
* @param contractResult - The result array returned by the contract
|
|
87
|
+
* @param errorSelectors - Optional custom error selector mapping (defaults to MAGNAFLOW_ERROR_SELECTORS)
|
|
88
|
+
* @returns Parsed error information
|
|
89
|
+
*/
|
|
90
|
+
export function parseContractError(contractResult, errorSelectors = MAGNAFLOW_ERROR_SELECTORS) {
|
|
91
|
+
if (!contractResult || contractResult.length === 0) {
|
|
92
|
+
return 'Unknown error';
|
|
93
|
+
}
|
|
94
|
+
// Contract errors typically return an error selector (4 bytes, 8 hex characters)
|
|
95
|
+
const errorSelector = Array.isArray(contractResult) ? contractResult[0] : contractResult;
|
|
96
|
+
if (typeof errorSelector === 'string') {
|
|
97
|
+
// Ensure 0x prefix exists
|
|
98
|
+
const selector = errorSelector.startsWith('0x') ? errorSelector : `0x${errorSelector}`;
|
|
99
|
+
// Check if it's a known error selector
|
|
100
|
+
if (errorSelectors[selector]) {
|
|
101
|
+
return errorSelectors[selector];
|
|
102
|
+
}
|
|
103
|
+
// If not a known error, return the raw selector
|
|
104
|
+
return `Unknown error: ${selector}`;
|
|
105
|
+
}
|
|
106
|
+
return 'Unable to parse error information';
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create a friendly error message from an error object
|
|
110
|
+
* @param error - Original error object
|
|
111
|
+
* @param defaultMessage - Default error message (default: 'Operation failed')
|
|
112
|
+
* @param errorSelectors - Optional custom error selector mapping (defaults to MAGNAFLOW_ERROR_SELECTORS)
|
|
113
|
+
* @returns Friendly error message
|
|
114
|
+
*/
|
|
115
|
+
export function createFriendlyErrorMessage(error, defaultMessage = 'Operation failed', errorSelectors = MAGNAFLOW_ERROR_SELECTORS) {
|
|
116
|
+
const parsedError = parseEvmError(error, errorSelectors);
|
|
117
|
+
// If parsed error differs from default message, use parsed error
|
|
118
|
+
if (parsedError !== 'Unknown error' && parsedError !== error.message) {
|
|
119
|
+
return `${defaultMessage}: ${parsedError}`;
|
|
120
|
+
}
|
|
121
|
+
// Otherwise use original error message or default message
|
|
122
|
+
return error?.message || defaultMessage;
|
|
123
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @magnaflow/contract-sdk
|
|
3
|
+
* Standardized contract interaction SDK for multi-chain smart contracts
|
|
4
|
+
*/
|
|
5
|
+
export type { Abi, EIP712Domain, ContractCallParams, ContractWriteParams, ContractTransactionResult, } from './types';
|
|
6
|
+
export { ContractManager } from './contract-manager';
|
|
7
|
+
export { ContractCaller } from './contract-caller';
|
|
8
|
+
export { signDigest } from './eip712-signer';
|
|
9
|
+
export { parseEvmError, parseContractError, createFriendlyErrorMessage, MAGNAFLOW_ERROR_SELECTORS, } from './error-handler';
|
|
10
|
+
export { payout_new_abi, ORDER_STRUCT_TYPE } from './payout-abi';
|
|
11
|
+
export { ERC20_ABI } from './erc20-abi';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,GAAG,EACH,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @magnaflow/contract-sdk
|
|
3
|
+
* Standardized contract interaction SDK for multi-chain smart contracts
|
|
4
|
+
*/
|
|
5
|
+
// Contract manager
|
|
6
|
+
export { ContractManager } from './contract-manager';
|
|
7
|
+
// Contract caller
|
|
8
|
+
export { ContractCaller } from './contract-caller';
|
|
9
|
+
// EIP-712 signing
|
|
10
|
+
export { signDigest } from './eip712-signer';
|
|
11
|
+
// Error handling
|
|
12
|
+
export { parseEvmError, parseContractError, createFriendlyErrorMessage, MAGNAFLOW_ERROR_SELECTORS, } from './error-handler';
|
|
13
|
+
// ABIs
|
|
14
|
+
export { payout_new_abi, ORDER_STRUCT_TYPE } from './payout-abi';
|
|
15
|
+
export { ERC20_ABI } from './erc20-abi';
|