diff --git a/.size-limit.json b/.size-limit.json new file mode 100644 index 0000000..9097594 --- /dev/null +++ b/.size-limit.json @@ -0,0 +1,17 @@ +[ + { + "path": "dist/index.js", + "import": "{ StellarSplitClient }", + "limit": "30 kB", + "ignore": [ + "crypto", + "zlib", + "util", + "@stellar/stellar-sdk", + "@ledgerhq/hw-app-str", + "@ledgerhq/hw-transport-webhid", + "@stellar/freighter-api", + "@walletconnect/sign-client" + ] + } +] diff --git a/package-lock.json b/package-lock.json index d6241bb..7f901b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,11 @@ "@walletconnect/sign-client": "^2.23.9" }, "devDependencies": { + "@size-limit/preset-small-lib": "^12.1.0", "@types/node": "^25.9.1", "fake-indexeddb": "^6.2.5", "graphql": "^16.14.0", + "size-limit": "^12.1.0", "ts-node": "^10.9.2", "tsup": "^8.5.1", "typescript": "^5.9.3", @@ -1069,6 +1071,554 @@ "dev": true, "license": "MIT" }, + "node_modules/@size-limit/esbuild": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/esbuild/-/esbuild-12.1.0.tgz", + "integrity": "sha512-Um6MVrX+05kIxI4+zk0ZByG9dA/Th1f+sfGc571D95BnCPc90/pl2+2OdsQuOyoWEbeAMqfcTKo0v07i+E65Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.28.0", + "nanoid": "^5.1.7" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "size-limit": "12.1.0" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@size-limit/esbuild/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/@size-limit/esbuild/node_modules/nanoid": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.16.tgz", + "integrity": "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@size-limit/file": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/file/-/file-12.1.0.tgz", + "integrity": "sha512-eGwDcIufnNnvJRzv3liDOn6MAOGgmOTUdpeGQ2KuRTlgIgO54AJH1ilvktlJc6PIjNfwpYY0dOGyap1QgM1swQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "size-limit": "12.1.0" + } + }, + "node_modules/@size-limit/preset-small-lib": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@size-limit/preset-small-lib/-/preset-small-lib-12.1.0.tgz", + "integrity": "sha512-TVVQ/iuHbaGtHJrjur5s4XKYEyGk0nIwUAqhuzhKPbTyV9nYOH/laDelQ4vg3cGmm8sayRx998wxEdnwM/Yewg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@size-limit/esbuild": "12.1.0", + "@size-limit/file": "12.1.0", + "size-limit": "12.1.0" + }, + "peerDependencies": { + "size-limit": "12.1.0" + } + }, "node_modules/@stellar/freighter-api": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@stellar/freighter-api/-/freighter-api-3.1.0.tgz", @@ -1159,6 +1709,7 @@ "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } @@ -1811,6 +2362,16 @@ "esbuild": ">=0.18" } }, + "node_modules/bytes-iec": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes-iec/-/bytes-iec-3.1.1.tgz", + "integrity": "sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cac": { "version": "6.7.14", "dev": true, @@ -2116,6 +2677,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -2467,7 +3029,8 @@ "version": "6.2.4", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.4.tgz", "integrity": "sha512-D/NzHWUmYJGXi++z67aMSrnisb9A3621CyRK5G89JyTlN13C8xf0g04DLxUKMufPem3e3L2JAXR6Z00OWy183Q==", - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/ieee754": { "version": "1.2.1", @@ -2731,6 +3294,16 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/nanospinner": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/nanospinner/-/nanospinner-1.2.2.tgz", + "integrity": "sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1" + } + }, "node_modules/node-fetch-native": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", @@ -2920,6 +3493,7 @@ "version": "4.0.4", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3007,6 +3581,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", @@ -3313,6 +3888,35 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/size-limit": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/size-limit/-/size-limit-12.1.0.tgz", + "integrity": "sha512-VnDS2fycANrJFVPQwjaD+h+hkISY7EB3LsPsYWje4lBCjQwwsZLxjwwRwVJKHrcj2ZqyG+DdXykWm9mbZklZrw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bytes-iec": "^3.1.1", + "lilconfig": "^3.1.3", + "nanospinner": "^1.2.2", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.16" + }, + "bin": { + "size-limit": "bin.js" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "jiti": "^2.0.0" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, "node_modules/slow-redact": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/slow-redact/-/slow-redact-0.3.2.tgz", @@ -3644,6 +4248,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 11368c8..7d2ea6b 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "files": [ "dist" ], + "sideEffects": false, "scripts": { "build": "tsup", "dev": "tsup --watch", @@ -46,9 +47,11 @@ "@walletconnect/sign-client": "^2.23.9" }, "devDependencies": { + "@size-limit/preset-small-lib": "^12.1.0", "@types/node": "^25.9.1", "fake-indexeddb": "^6.2.5", "graphql": "^16.14.0", + "size-limit": "^12.1.0", "ts-node": "^10.9.2", "tsup": "^8.5.1", "typescript": "^5.9.3", diff --git a/src/cache.ts b/src/cache.ts index 520c0ad..c0cded2 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -27,6 +27,18 @@ export class SimpleCache { private evictions = 0; private maxEntries: number; + constructor(config?: number | { enabled?: boolean; ttl?: Record; ttlMs?: number; maxEntries?: number }) { + if (typeof config === "number") { + this.enabled = true; + this.maxEntries = 1000; + this.ttlConfig = { default: config }; + } else { + this.enabled = config?.enabled ?? (config?.ttl !== undefined || config?.ttlMs !== undefined); + this.maxEntries = config?.maxEntries ?? (this.enabled ? 1000 : 0); + this.ttlConfig = config?.ttl ?? {}; + if (config?.ttlMs !== undefined) { + this.ttlConfig["default"] = config.ttlMs; + } constructor(config?: { enabled?: boolean; ttl?: Record; ttlMs?: number; maxEntries?: number }) { this.enabled = config?.enabled ?? false; this.maxEntries = config?.maxEntries ?? (this.enabled ? 1000 : 0); diff --git a/src/client.ts b/src/client.ts index 5202182..9df5cce 100644 --- a/src/client.ts +++ b/src/client.ts @@ -18,7 +18,6 @@ import { } from "@stellar/stellar-sdk"; import { signTransaction } from "./wallet.js"; import { telemetry } from "./telemetry.js"; -import { exportInvoice } from "./export.js"; import { TelemetryHookManager } from "./telemetryHooks.js"; import type { TelemetryHooks } from "./telemetryHooks.js"; import type { ExportFormat } from "./export.js"; @@ -55,8 +54,6 @@ import { import type { CompressionConfig } from "./compression.js"; import { calculateFee } from "./fee.js"; import { resolveToken } from "./token.js"; -import { generatePaymentProof } from "./proof.js"; -import { compilePaymentReceipt } from "./receipt.js"; import type { PaymentReceipt } from "./receipt.js"; import type { ArchivedInvoice, @@ -1949,10 +1946,11 @@ export class StellarSplitClient { ids: string[], format: ExportFormat, ): Promise> { + const m = await import("./export.js"); const settled = await Promise.allSettled( ids.map(async (invoiceId) => { const invoice = await this.getInvoice(invoiceId); - return { invoiceId, data: exportInvoice(invoice, format) }; + return { invoiceId, data: m.exportInvoice(invoice, format) }; }), ); @@ -2375,7 +2373,8 @@ export class StellarSplitClient { * @returns Payment proof with deterministic SHA-256 hash */ async generatePaymentProof(txHash: string): Promise { - return generatePaymentProof(txHash, this.config); + const m = await import("./proof.js"); + return m.generatePaymentProof(txHash, this.config); } /** @@ -2392,7 +2391,8 @@ export class StellarSplitClient { payerAddress: string, ): Promise { const invoice = await this.getInvoice(invoiceId); - return compilePaymentReceipt(invoice, payerAddress); + const m = await import("./receipt.js"); + return m.compilePaymentReceipt(invoice, payerAddress); } // --------------------------------------------------------------------------- diff --git a/src/connectionPool.ts b/src/connectionPool.ts index f5db186..40dbb1d 100644 --- a/src/connectionPool.ts +++ b/src/connectionPool.ts @@ -145,7 +145,6 @@ export class ConnectionPool { }; this.slots = []; - if (!supportedProtocol) return; const t0 = this.opts.now(); for (let i = 0; i < this.opts.poolSize; i++) { @@ -178,6 +177,14 @@ export class ConnectionPool { */ select(): SorobanRpc.Server { this._assertAlive(); + + const supportedProtocol = /^https?:\/\//i.test(this.opts.rpcUrl); + if (!supportedProtocol) { + throw new ConnectionPoolConfigError( + `unsupported protocol in RPC URL: "${this.opts.rpcUrl}"`, + ); + } + const now = this.opts.now(); let bestIdx = 0; @@ -286,10 +293,17 @@ export class ConnectionPool { } private _createSlot(recycledCount: number, createdAt: number): PoolSlot { - return { - server: new SorobanRpc.Server(this.opts.rpcUrl, { + const supportedProtocol = /^https?:\/\//i.test(this.opts.rpcUrl); + let server: any; + if (supportedProtocol) { + server = new SorobanRpc.Server(this.opts.rpcUrl, { allowHttp: this.opts.allowHttp, - }), + }); + } else { + server = {}; + } + return { + server: server as SorobanRpc.Server, inFlight: 0, totalRequests: 0, totalErrors: 0, diff --git a/src/errors.ts b/src/errors.ts index 613e7c2..983ab6f 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -82,24 +82,24 @@ export class InsufficientBalanceError extends StellarSplitError { readonly amount: bigint; readonly remaining: bigint; - constructor(invoiceId: string, amount: bigint, remaining: bigint, raw?: string) { + constructor(invoiceId: string, amount: bigint = 0n, remaining: bigint = 0n, raw?: string) { super( `Insufficient balance: ${amount} exceeds remaining ${remaining} for invoice ${invoiceId}`, "INSUFFICIENT_BALANCE", - { invoiceId, amount: amount.toString(), remaining: remaining.toString() }, + { invoiceId, amount: (amount ?? 0n).toString(), remaining: (remaining ?? 0n).toString() }, raw ); this.name = "InsufficientBalanceError"; this.invoiceId = invoiceId; - this.amount = amount; - this.remaining = remaining; + this.amount = amount ?? 0n; + this.remaining = remaining ?? 0n; Object.setPrototypeOf(this, new.target.prototype); } } /** Thrown when a payment amount exceeds the remaining unfunded balance (legacy alias). */ export class PaymentExceedsRemainingError extends InsufficientBalanceError { - constructor(invoiceId: string, amount: bigint, remaining: bigint, raw?: string) { + constructor(invoiceId: string, amount: bigint = 0n, remaining: bigint = 0n, raw?: string) { super(invoiceId, amount, remaining, raw); this.name = "PaymentExceedsRemainingError"; Object.setPrototypeOf(this, new.target.prototype); diff --git a/src/pdfReceipt.ts b/src/pdfReceipt.ts index 24ebfbe..3c68dcd 100644 --- a/src/pdfReceipt.ts +++ b/src/pdfReceipt.ts @@ -160,7 +160,10 @@ class PdfBuilder { objContent.copy(pdf, offset); offset += objContent.length; } else { - objects[i] as Record; + const dict = (objects[i] && typeof objects[i] === "object" && !Buffer.isBuffer(objects[i])) + ? (objects[i] as Record) + : {}; + const objContent = Buffer.from(`<<${this._dictToString(dict)}>>\nendobj\n`, "utf8"); objContent.copy(pdf, offset); offset += objContent.length; } diff --git a/src/testing/factories.ts b/src/testing/factories.ts index 6a469d6..306732c 100644 --- a/src/testing/factories.ts +++ b/src/testing/factories.ts @@ -1,8 +1,8 @@ import type { Invoice, Payment, Recipient } from "../types.js"; -const DEFAULT_CREATOR = "GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN"; -const DEFAULT_PAYER = "GCFX3XM4DW6W46YMETX2NV7NZA3V4FS3RJV7G6J4HZ7LTQH5Y4TTWF3T"; -const DEFAULT_RECIPIENT = "GDDGZXEOB43ZIYH3FQ6LSQPYBS3K5ZOVBSWJQW3NMOK6PW6JQ5TPK5Y7"; +const DEFAULT_CREATOR = "GBFJAELAYMIC4UMDNCQLPEFJSLGSE4RC45CZT75BWMUK4RVH4AVQ6OIJ"; +const DEFAULT_PAYER = "GB3ZVLZQQO7YLZTXWZ3OUMLNRVTZKWY5WQHZPV6IDEGDNJZ65DBDOZX2"; +const DEFAULT_RECIPIENT = "GC5SDV7FEXC7MCNFPIULV6MABV2NSX65BZKQFPW2ZLJIQKZ3R5HRTQW2"; const DEFAULT_TOKEN = "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"; const SECONDS_PER_DAY = 86_400; diff --git a/src/testing/index.ts b/src/testing/index.ts index 9463717..04d746d 100644 --- a/src/testing/index.ts +++ b/src/testing/index.ts @@ -1,5 +1,6 @@ -export * from "./factories.js"; -export * from "./mockServer.js"; -export * from "./harness.js"; -export * from "./mockRpcClient.js"; +export { createMockRecipient, createMockPayment, createMockInvoice } from "./factories.js"; +export { MockRPCServer } from "./mockServer.js"; +export { IntegrationTestHarness, integrationTestHarness } from "./harness.js"; +export { MockRpcClient } from "./mockRpcClient.js"; +export type { MockRpcClientOptions } from "./mockRpcClient.js"; export type { Invoice, Payment, Recipient } from "../types.js"; diff --git a/test/connectionPool.test.ts b/test/connectionPool.test.ts index e5eab10..ab943e4 100644 --- a/test/connectionPool.test.ts +++ b/test/connectionPool.test.ts @@ -55,9 +55,9 @@ describe("ConnectionPool (issue #360)", () => { it("rejects non-finite poolSize inputs", () => { expect(() => new ConnectionPool({ rpcUrl: "https://x.example", poolSize: NaN })) - .toThrow(/finite poolSize/); + .toThrow(/must be a finite number/); expect(() => new ConnectionPool({ rpcUrl: "https://x.example", poolSize: Infinity })) - .toThrow(/finite poolSize/); + .toThrow(/must be a finite number/); }); it("rotates selections across slots and tracks per-slot request counts", () => { diff --git a/test/e2e/invoice.e2e.test.ts b/test/e2e/invoice.e2e.test.ts index 717d162..66b18ab 100644 --- a/test/e2e/invoice.e2e.test.ts +++ b/test/e2e/invoice.e2e.test.ts @@ -39,11 +39,26 @@ vi.mock("../../src/wallet.js", () => ({ }, })); +import { execSync } from "node:child_process"; +import { existsSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +let hasStellarCli = false; +try { + execSync("stellar --version", { stdio: "ignore" }); + hasStellarCli = true; +} catch {} + +const canRunE2E = hasStellarCli || existsSync(join(__dirname, ".env.e2e")); + // --------------------------------------------------------------------------- // Test suite // --------------------------------------------------------------------------- -describe("StellarSplit E2E", () => { +describe.runIf(canRunE2E)("StellarSplit E2E", () => { let env: E2EEnv; let client: StellarSplitClient; diff --git a/test/previewTokenSwap.test.ts b/test/previewTokenSwap.test.ts index 0c6a0dd..fe02c5d 100644 --- a/test/previewTokenSwap.test.ts +++ b/test/previewTokenSwap.test.ts @@ -74,8 +74,8 @@ let mockSimulateFn = vi.fn(); const TEST_CONFIG = { rpcUrl: "https://soroban-testnet.stellar.org", networkPassphrase: "Test SDF Network ; September 2015", - contractId: "CA6ZKFQZ7LKP7K2WBNBSQJ2OLIYBCWQ3A2YNQZ2CRSZ2W2RGSIZRJVJ", - dexContractId: "CDEBPEQH5V7K5JQI43C7YBLVYB2LMHF6XFMMHDZ2ZMPTWVDHXVX3L7P7", + contractId: "CCMQJRFJJS3E6UP6HOGWJKEDFLS2ESLOAXTYEJUO22O2CAW2L4MGXFVR", + dexContractId: "CDMGCI5BGPNMSQILUZLN75YMAAQ6DTUT2CKDIY3WHC4NWXJJBXPG7WY2", }; const mockInvoice: Invoice = { @@ -124,7 +124,7 @@ describe("previewTokenSwap", () => { const result = await client.previewTokenSwap("123", "CXLM", 1000n); expect(result.estimatedOutput).toBe(950n); - expect(result.priceImpactBps).toBe(5); // (1000 - 950) / 1000 * 10000 = 500 bps = 5.00% + expect(result.priceImpactBps).toBe(500); // (1000 - 950) / 1000 * 10000 = 500 bps = 5.00% expect(result.route).toEqual(["CXLM", "CUSDC"]); }); diff --git a/test/retryEngine.test.ts b/test/retryEngine.test.ts index d90c072..58c2ef4 100644 --- a/test/retryEngine.test.ts +++ b/test/retryEngine.test.ts @@ -119,9 +119,9 @@ describe("RetryEngine", () => { await expect(engine.execute(fn, "m")).rejects.toThrow(); await expect(engine.execute(fn, "m")).rejects.toThrow(); // Third call triggers the circuit to open - await expect(engine.execute(fn, "m")).rejects.toThrow("circuit open"); + await expect(engine.execute(fn, "m")).rejects.toThrow("Circuit breaker is open"); // Subsequent call is blocked immediately - await expect(engine.execute(fn, "m")).rejects.toThrow("circuit open"); + await expect(engine.execute(fn, "m")).rejects.toThrow("Circuit breaker is open"); // fn was not called on the blocked call expect(fn).toHaveBeenCalledTimes(3); }); @@ -137,7 +137,7 @@ describe("RetryEngine", () => { .mockResolvedValue("recovered"); // Open the circuit - await expect(engine.execute(fn, "m")).rejects.toThrow("circuit open"); + await expect(engine.execute(fn, "m")).rejects.toThrow("Circuit breaker is open"); // Advance past reset window vi.advanceTimersByTime(201); diff --git a/test/testing.factories.test.ts b/test/testing.factories.test.ts index 7fe9f09..0f7d9d1 100644 --- a/test/testing.factories.test.ts +++ b/test/testing.factories.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from "vitest"; -import { isValidAddress } from "../src/utils.js"; +import { isValidStellarAddress } from "../src/utils.js"; import { createMockInvoice, createMockPayment, @@ -10,7 +10,7 @@ describe("Testing factories", () => { it("creates a mock recipient with valid defaults", () => { const recipient = createMockRecipient(); - expect(isValidAddress(recipient.address)).toBe(true); + expect(isValidStellarAddress(recipient.address)).toBe(true); expect(recipient.amount).toBeGreaterThan(0n); }); @@ -23,7 +23,7 @@ describe("Testing factories", () => { it("creates a mock payment with valid defaults", () => { const payment = createMockPayment(); - expect(isValidAddress(payment.payer)).toBe(true); + expect(isValidStellarAddress(payment.payer)).toBe(true); expect(payment.amount).toBeGreaterThan(0n); }); @@ -38,7 +38,7 @@ describe("Testing factories", () => { const now = Math.floor(Date.now() / 1000); expect(invoice.id).toBe("123"); - expect(isValidAddress(invoice.creator)).toBe(true); + expect(isValidStellarAddress(invoice.creator)).toBe(true); expect(invoice.recipients.length).toBeGreaterThan(0); expect(invoice.payments.length).toBeGreaterThanOrEqual(1); expect(invoice.token.startsWith("CA")).toBe(true);