@palindromepay/sdk 2.0.6 → 2.0.7

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 CHANGED
@@ -10,7 +10,22 @@ A TypeScript/Node SDK for interacting with the PalindromePay escrow smart contra
10
10
 
11
11
  ## 📚 Documentation
12
12
 
13
- **Full documentation available at: [sdk.palindromepay.com](https://sdk.palindromepay.com)**
13
+ **Full documentation available at: [palindromepay.com/sdk](https://www.palindromepay.com/sdk)**
14
+
15
+ ---
16
+
17
+ ## ✨ Features
18
+
19
+ - Interact with on-chain escrow contracts using public & wallet clients
20
+ - Supports ERC20 deposits, fee calculation, and contract state queries
21
+ - Buyer, Seller, Arbiter roles—plus dispute/resolve logic
22
+ - Meta-transaction signature helpers (EIP-712 compatible)
23
+ - Auto-release and time/maturity helpers
24
+ - Subgraph GraphQL queries to fetch and filter escrows and dispute messages
25
+ - Flexible error classes and codes for wallet/client state
26
+ - Utilities for fee calculation, token formatting, deadlines, and maturity times
27
+ - Gas estimation helpers for transaction planning
28
+ - Comprehensive state and role validation helpers
14
29
 
15
30
  ---
16
31
 
@@ -67,4 +82,4 @@ Contributions are welcome! Please feel free to submit a Pull Request.
67
82
  ## 📞 Support
68
83
 
69
84
  - GitHub Issues: https://github.com/palindromepay/SDKPalindromePay/issues
70
- - Documentation: https://sdk.palindromepay.com
85
+ - Documentation: https://www.palindromepay.com/sdk
@@ -99,7 +99,8 @@ export interface PalindromePaySDKConfig {
99
99
  publicClient: PublicClient;
100
100
  contractAddress: Address;
101
101
  walletClient?: EscrowWalletClient;
102
- apolloClient?: ApolloClient;
102
+ /** Apollo client for subgraph queries (required) */
103
+ apolloClient: ApolloClient;
103
104
  chain?: Chain;
104
105
  /** Cache TTL in milliseconds (default: 5000) */
105
106
  cacheTTL?: number;
@@ -115,7 +116,6 @@ export interface PalindromePaySDKConfig {
115
116
  gasBuffer?: number;
116
117
  /** Transaction receipt timeout in milliseconds (default: 60000) */
117
118
  receiptTimeout?: number;
118
- subgraphUrl?: string;
119
119
  /**
120
120
  * Skip eth_call simulation before sending transactions (default: false)
121
121
  * Enable this for chains with unreliable RPC simulation (e.g., Base Sepolia)
@@ -237,6 +237,8 @@ export declare class PalindromePaySDK {
237
237
  private tokenDecimalsCache;
238
238
  /** Cache for immutable contract values */
239
239
  private feeReceiverCache;
240
+ /** Cached default arbiter from contract (immutable) */
241
+ private defaultArbiterCache;
240
242
  /** Cached multicall support status per chain (null = not yet detected) */
241
243
  private multicallSupported;
242
244
  private readonly STATE_NAMES;
@@ -1214,6 +1216,20 @@ export declare class PalindromePaySDK {
1214
1216
  * @param forceRefresh - Set to true to bypass cache and fetch fresh value
1215
1217
  */
1216
1218
  getFeeReceiver(forceRefresh?: boolean): Promise<Address>;
1219
+ /**
1220
+ * Check if an escrow uses the default Palindrome Pay arbiter.
1221
+ *
1222
+ * @param escrow - The escrow data to check
1223
+ * @returns True if the escrow uses the default arbiter
1224
+ */
1225
+ isDefaultArbiter(escrow: EscrowData): Promise<boolean>;
1226
+ /**
1227
+ * Get the default Palindrome Pay arbiter address from contract.
1228
+ * Result is cached since the value is immutable.
1229
+ *
1230
+ * @returns The default arbiter address
1231
+ */
1232
+ getDefaultArbiter(): Promise<Address>;
1217
1233
  /** Cached fee basis points (lazily computed from contract) */
1218
1234
  private cachedFeeBps;
1219
1235
  /**
@@ -30,7 +30,6 @@ const actions_1 = require("viem/actions");
30
30
  const PalindromePay_json_1 = __importDefault(require("./contract/PalindromePay.json"));
31
31
  const PalindromePayWallet_json_1 = __importDefault(require("./contract/PalindromePayWallet.json"));
32
32
  const USDT_json_1 = __importDefault(require("./contract/USDT.json"));
33
- const client_1 = require("@apollo/client");
34
33
  /** Type guard to check if error is a Viem error */
35
34
  function isViemError(error) {
36
35
  return (typeof error === 'object' &&
@@ -100,6 +99,8 @@ const MAX_STRING_LENGTH = 500;
100
99
  const USER_REJECTION_CODE = 4001;
101
100
  /** Seconds per day for maturity calculations */
102
101
  const SECONDS_PER_DAY = 86400n;
102
+ /** Maximum maturity days (10 years) */
103
+ const MAX_MATURITY_DAYS = 3650n;
103
104
  /** Nonce bitmap word size in bits */
104
105
  const NONCE_BITMAP_SIZE = 256;
105
106
  /** Default cache TTL in milliseconds */
@@ -201,6 +202,8 @@ class PalindromePaySDK {
201
202
  this.tokenDecimalsCache = new Map();
202
203
  /** Cache for immutable contract values */
203
204
  this.feeReceiverCache = null;
205
+ /** Cached default arbiter from contract (immutable) */
206
+ this.defaultArbiterCache = null;
204
207
  /** Cached multicall support status per chain (null = not yet detected) */
205
208
  this.multicallSupported = null;
206
209
  this.STATE_NAMES = [
@@ -267,12 +270,10 @@ class PalindromePaySDK {
267
270
  this.defaultGasLimit = config.defaultGasLimit ?? 500000n;
268
271
  this.logLevel = config.logLevel ?? 'info';
269
272
  this.logger = config.logger ?? (this.logLevel === 'none' ? noOpLogger : defaultLogger);
270
- this.apollo = config.apolloClient ?? new client_1.ApolloClient({
271
- link: new client_1.HttpLink({
272
- uri: config.subgraphUrl ?? "https://api.studio.thegraph.com/query/121986/palindrome-finance-subgraph/version/latest",
273
- }),
274
- cache: new client_1.InMemoryCache(),
275
- });
273
+ if (!config.apolloClient) {
274
+ throw new SDKError("apolloClient is required", SDKErrorCode.VALIDATION_ERROR);
275
+ }
276
+ this.apollo = config.apolloClient;
276
277
  }
277
278
  // ==========================================================================
278
279
  // PRIVATE HELPERS
@@ -419,6 +420,9 @@ class PalindromePaySDK {
419
420
  if (maturityDays < 0n) {
420
421
  throw new SDKError("Maturity days cannot be negative", SDKErrorCode.VALIDATION_ERROR);
421
422
  }
423
+ if (maturityDays > MAX_MATURITY_DAYS) {
424
+ throw new SDKError(`Maturity days cannot exceed ${MAX_MATURITY_DAYS} days (10 years)`, SDKErrorCode.VALIDATION_ERROR);
425
+ }
422
426
  if (!title || title.trim().length === 0) {
423
427
  throw new SDKError("Title cannot be empty", SDKErrorCode.VALIDATION_ERROR);
424
428
  }
@@ -1041,10 +1045,19 @@ class PalindromePaySDK {
1041
1045
  // Validate and normalize addresses
1042
1046
  const token = validateAddress(params.token, "token");
1043
1047
  const buyer = validateAddress(params.buyer, "buyer");
1044
- const arbiter = params.arbiter
1045
- ? validateAddress(params.arbiter, "arbiter")
1046
- : viem_1.zeroAddress;
1047
1048
  const sellerAddress = walletClient.account.address;
1049
+ // Use default arbiter if none provided, reject zero address
1050
+ let arbiter;
1051
+ if (params.arbiter) {
1052
+ const validatedArbiter = validateAddress(params.arbiter, "arbiter");
1053
+ if (isZeroAddress(validatedArbiter)) {
1054
+ throw new SDKError("Zero address not allowed for arbiter. Omit arbiter param to use Palindrome Pay default.", SDKErrorCode.VALIDATION_ERROR);
1055
+ }
1056
+ arbiter = validatedArbiter;
1057
+ }
1058
+ else {
1059
+ arbiter = await this.getDefaultArbiter();
1060
+ }
1048
1061
  const maturityDays = params.maturityTimeDays ?? 1n;
1049
1062
  // Validate using helper
1050
1063
  this.validateCreateEscrowParams({
@@ -1057,13 +1070,11 @@ class PalindromePaySDK {
1057
1070
  title: params.title,
1058
1071
  });
1059
1072
  // Validate arbiter is not buyer or seller
1060
- if (!isZeroAddress(arbiter)) {
1061
- if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(buyer)) {
1062
- throw new SDKError("Arbiter cannot be the buyer", SDKErrorCode.VALIDATION_ERROR);
1063
- }
1064
- if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(sellerAddress)) {
1065
- throw new SDKError("Arbiter cannot be the seller", SDKErrorCode.VALIDATION_ERROR);
1066
- }
1073
+ if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(buyer)) {
1074
+ throw new SDKError("Arbiter cannot be the buyer", SDKErrorCode.VALIDATION_ERROR);
1075
+ }
1076
+ if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(sellerAddress)) {
1077
+ throw new SDKError("Arbiter cannot be the seller", SDKErrorCode.VALIDATION_ERROR);
1067
1078
  }
1068
1079
  const ipfsHash = params.ipfsHash ?? "";
1069
1080
  // Predict next escrow ID and wallet address
@@ -1158,10 +1169,19 @@ class PalindromePaySDK {
1158
1169
  // Validate and normalize addresses
1159
1170
  const token = validateAddress(params.token, "token");
1160
1171
  const seller = validateAddress(params.seller, "seller");
1161
- const arbiter = params.arbiter
1162
- ? validateAddress(params.arbiter, "arbiter")
1163
- : viem_1.zeroAddress;
1164
1172
  const buyerAddress = walletClient.account.address;
1173
+ // Use default arbiter if none provided, reject zero address
1174
+ let arbiter;
1175
+ if (params.arbiter) {
1176
+ const validatedArbiter = validateAddress(params.arbiter, "arbiter");
1177
+ if (isZeroAddress(validatedArbiter)) {
1178
+ throw new SDKError("Zero address not allowed for arbiter. Omit arbiter param to use Palindrome Pay default.", SDKErrorCode.VALIDATION_ERROR);
1179
+ }
1180
+ arbiter = validatedArbiter;
1181
+ }
1182
+ else {
1183
+ arbiter = await this.getDefaultArbiter();
1184
+ }
1165
1185
  const maturityDays = params.maturityTimeDays ?? 1n;
1166
1186
  // Validate using helper
1167
1187
  this.validateCreateEscrowParams({
@@ -1174,13 +1194,11 @@ class PalindromePaySDK {
1174
1194
  title: params.title,
1175
1195
  });
1176
1196
  // Validate arbiter is not buyer or seller
1177
- if (!isZeroAddress(arbiter)) {
1178
- if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(seller)) {
1179
- throw new SDKError("Arbiter cannot be the seller", SDKErrorCode.VALIDATION_ERROR);
1180
- }
1181
- if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(buyerAddress)) {
1182
- throw new SDKError("Arbiter cannot be the buyer", SDKErrorCode.VALIDATION_ERROR);
1183
- }
1197
+ if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(seller)) {
1198
+ throw new SDKError("Arbiter cannot be the seller", SDKErrorCode.VALIDATION_ERROR);
1199
+ }
1200
+ if ((0, viem_1.getAddress)(arbiter) === (0, viem_1.getAddress)(buyerAddress)) {
1201
+ throw new SDKError("Arbiter cannot be the buyer", SDKErrorCode.VALIDATION_ERROR);
1184
1202
  }
1185
1203
  const ipfsHash = params.ipfsHash ?? "";
1186
1204
  // Approve token spending
@@ -2189,6 +2207,7 @@ class PalindromePaySDK {
2189
2207
  this.escrowCache.clear();
2190
2208
  this.tokenDecimalsCache.clear();
2191
2209
  this.feeReceiverCache = null;
2210
+ this.defaultArbiterCache = null;
2192
2211
  this.cachedFeeBps = null;
2193
2212
  this.multicallSupported = null;
2194
2213
  await this.clearApolloCache();
@@ -2814,6 +2833,34 @@ class PalindromePaySDK {
2814
2833
  });
2815
2834
  return this.feeReceiverCache;
2816
2835
  }
2836
+ /**
2837
+ * Check if an escrow uses the default Palindrome Pay arbiter.
2838
+ *
2839
+ * @param escrow - The escrow data to check
2840
+ * @returns True if the escrow uses the default arbiter
2841
+ */
2842
+ async isDefaultArbiter(escrow) {
2843
+ const defaultArbiter = await this.getDefaultArbiter();
2844
+ return escrow.arbiter.toLowerCase() === defaultArbiter.toLowerCase();
2845
+ }
2846
+ /**
2847
+ * Get the default Palindrome Pay arbiter address from contract.
2848
+ * Result is cached since the value is immutable.
2849
+ *
2850
+ * @returns The default arbiter address
2851
+ */
2852
+ async getDefaultArbiter() {
2853
+ if (this.defaultArbiterCache) {
2854
+ return this.defaultArbiterCache;
2855
+ }
2856
+ const arbiter = await (0, actions_1.readContract)(this.publicClient, {
2857
+ address: this.contractAddress,
2858
+ abi: PalindromePay_json_1.default.abi,
2859
+ functionName: "DEFAULT_ARBITER",
2860
+ });
2861
+ this.defaultArbiterCache = arbiter;
2862
+ return this.defaultArbiterCache;
2863
+ }
2817
2864
  /**
2818
2865
  * Get fee percentage in basis points.
2819
2866
  * Tries to read FEE_BPS from contract, falls back to default (100 = 1%).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palindromepay/sdk",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
4
4
  "description": "TypeScript SDK for PalindromeCryptoEscrow - Secure blockchain escrow with buyer/seller protection",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,7 +34,7 @@
34
34
  "bugs": {
35
35
  "url": "https://github.com/palindromepay/SDKPalindromePay/issues"
36
36
  },
37
- "homepage": "https://sdk.palindromepay.com",
37
+ "homepage": "https://www.palindromepay.com/sdk",
38
38
  "files": [
39
39
  "dist",
40
40
  "README.md",
@@ -56,6 +56,9 @@
56
56
  "undici-types": "^7.16.0",
57
57
  "viem": "^2.38.0"
58
58
  },
59
+ "peerDependencies": {
60
+ "@apollo/client": "^4.0.0"
61
+ },
59
62
  "devDependencies": {
60
63
  "@apollo/client": "^4.0.7",
61
64
  "@types/jest": "^30.0.0",