@toon-protocol/sdk 2.2.0 → 3.0.0
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 +5 -5
- package/dist/index.d.ts +8 -3
- package/dist/index.js +40 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ const result = await node.start();
|
|
|
60
60
|
console.log(`Connected to ${result.peerCount} peers`);
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
> **Easier path:** If you just want to run a relay, use [`@toon-protocol/
|
|
63
|
+
> **Easier path:** If you just want to run a relay, use [`@toon-protocol/relay`](https://github.com/toon-protocol/relay) — it wraps the SDK with sensible defaults and runs out of the box. The SDK is for building custom services where you control the full pipeline.
|
|
64
64
|
|
|
65
65
|
## Where It Sits
|
|
66
66
|
|
|
@@ -100,17 +100,17 @@ The SDK is the framework layer. You bring handlers; it handles the protocol.
|
|
|
100
100
|
| **Self-write bypass** | Events from your own pubkey skip pricing |
|
|
101
101
|
| **Dev mode** | Skip verification and pricing for testing |
|
|
102
102
|
| **[TOON](https://github.com/toon-format/toon) encoding** | Events encoded in compact text format, not JSON |
|
|
103
|
-
| **Address assignment** | ILP addresses are derived from peering topology — your upstream peer assigns your address automatically based on your pubkey. A node with multiple upstream peers has multiple addresses. See [Protocol — ILP Address Hierarchy](
|
|
103
|
+
| **Address assignment** | ILP addresses are derived from peering topology — your upstream peer assigns your address automatically based on your pubkey. A node with multiple upstream peers has multiple addresses. See [Protocol — ILP Address Hierarchy](https://github.com/toon-protocol/toon-meta/blob/main/docs/protocol.md#ilp-address-hierarchy) |
|
|
104
104
|
| **Invisible fee calculation** | The SDK computes multi-hop fees internally. Each intermediary advertises a fee-per-byte; the SDK sums them along the route so `publishEvent()` callers pay one total amount |
|
|
105
105
|
|
|
106
106
|
## Full Documentation
|
|
107
107
|
|
|
108
|
-
See the [SDK Guide](
|
|
108
|
+
See the [SDK Guide](https://github.com/toon-protocol/toon-meta/blob/main/docs/sdk-guide.md) for the complete API reference, handler patterns, verification pipeline details, publishing events, and error handling.
|
|
109
109
|
|
|
110
110
|
## Requirements
|
|
111
111
|
|
|
112
|
-
- Node.js >=
|
|
113
|
-
- `@toon-protocol/connector` >=
|
|
112
|
+
- Node.js >= 22
|
|
113
|
+
- `@toon-protocol/connector` >= 3.3.3 (peer dependency, optional)
|
|
114
114
|
|
|
115
115
|
## License
|
|
116
116
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ToonError, HandlePacketAcceptResponse, HandlePacketRejectResponse, ReputationScore, SkillDescriptor, EmbeddableConnectorLike, KnownPeer, SettlementConfig, ChainProviderConfigEntry, ConnectorChannelClient, BootstrapEventListener, BootstrapResult, DvmJobStatus, IlpSendResult, ParsedWorkflowDefinition, SwapPair } from '@toon-protocol/core';
|
|
2
|
-
export { BootstrapEvent, BootstrapEventListener, HandlePacketAcceptResponse, HandlePacketRejectResponse, SkillDescriptor, balanceProofFieldsMina, balanceProofHashEvm, balanceProofHashSolana, bigintToBytes32BE, concatBytes, hexToBytes, minaHashToField } from '@toon-protocol/core';
|
|
2
|
+
export { BootstrapEvent, BootstrapEventListener, HandlePacketAcceptResponse, HandlePacketRejectResponse, SkillDescriptor, balanceProofFieldsMina, balanceProofHashEvm, balanceProofHashSolana, bigintToBytes32BE, concatBytes, coopCloseHashEvm, eip712DomainSeparatorEvm, hexToBytes, minaHashToField } from '@toon-protocol/core';
|
|
3
3
|
import { NostrEvent, UnsignedEvent } from 'nostr-tools/pure';
|
|
4
4
|
import { ToonRoutingMeta } from '@toon-protocol/core/toon';
|
|
5
5
|
import { TransportConfig } from '@toon-protocol/connector';
|
|
@@ -1788,7 +1788,10 @@ interface SwapSignerConfig {
|
|
|
1788
1788
|
*/
|
|
1789
1789
|
address: string;
|
|
1790
1790
|
/**
|
|
1791
|
-
* On-chain payment-channel contract address (EVM-only).
|
|
1791
|
+
* On-chain payment-channel contract address (EVM-only). Required for EVM
|
|
1792
|
+
* claims: it is the RLP `to` field AND the EIP-712 `verifyingContract` of the
|
|
1793
|
+
* v2 balance-proof digest (connector#324 finding #1), so it now binds the
|
|
1794
|
+
* signature to this exact deployment.
|
|
1792
1795
|
*/
|
|
1793
1796
|
contractAddress?: string;
|
|
1794
1797
|
/**
|
|
@@ -1796,7 +1799,9 @@ interface SwapSignerConfig {
|
|
|
1796
1799
|
*/
|
|
1797
1800
|
programId?: string;
|
|
1798
1801
|
/**
|
|
1799
|
-
* EVM chain-id (decimal). Required for EVM claims — baked into RLP per EIP-155
|
|
1802
|
+
* EVM chain-id (decimal). Required for EVM claims — baked into RLP per EIP-155
|
|
1803
|
+
* AND into the EIP-712 domain `chainId` of the v2 balance-proof digest
|
|
1804
|
+
* (connector#324 finding #1), so the signature is valid on this chain only.
|
|
1800
1805
|
*/
|
|
1801
1806
|
chainId?: number;
|
|
1802
1807
|
}
|
package/dist/index.js
CHANGED
|
@@ -2374,6 +2374,8 @@ import {
|
|
|
2374
2374
|
bigintToBytes32BE,
|
|
2375
2375
|
concatBytes,
|
|
2376
2376
|
balanceProofHashEvm,
|
|
2377
|
+
coopCloseHashEvm,
|
|
2378
|
+
eip712DomainSeparatorEvm,
|
|
2377
2379
|
balanceProofHashSolana,
|
|
2378
2380
|
minaHashToField,
|
|
2379
2381
|
balanceProofFieldsMina
|
|
@@ -2388,7 +2390,19 @@ var EVM_SETTLEMENT_FUNCTION_SELECTOR = keccak_256(
|
|
|
2388
2390
|
var EVM_SETTLEMENT_EVENT_TOPIC = "0x" + bytesToHex(
|
|
2389
2391
|
keccak_256(new TextEncoder().encode(EVM_SETTLEMENT_EVENT_SIGNATURE))
|
|
2390
2392
|
);
|
|
2391
|
-
function recoverEvmSignerAddress(claim) {
|
|
2393
|
+
function recoverEvmSignerAddress(claim, chainId, verifyingContract) {
|
|
2394
|
+
if (typeof chainId !== "number" || !Number.isInteger(chainId) || chainId <= 0) {
|
|
2395
|
+
throw new SettlementTxError(
|
|
2396
|
+
"INVALID_INPUT",
|
|
2397
|
+
`EVM v2 digest requires a positive integer chainId, got ${chainId}`
|
|
2398
|
+
);
|
|
2399
|
+
}
|
|
2400
|
+
if (!verifyingContract) {
|
|
2401
|
+
throw new SettlementTxError(
|
|
2402
|
+
"INVALID_INPUT",
|
|
2403
|
+
"EVM v2 digest requires verifyingContract (RollingSwapChannel address)"
|
|
2404
|
+
);
|
|
2405
|
+
}
|
|
2392
2406
|
if (claim.channelId === void 0 || claim.cumulativeAmount === void 0 || claim.nonce === void 0 || claim.recipient === void 0) {
|
|
2393
2407
|
throw new SettlementTxError(
|
|
2394
2408
|
"MISSING_SETTLEMENT_METADATA",
|
|
@@ -2415,6 +2429,7 @@ function recoverEvmSignerAddress(claim) {
|
|
|
2415
2429
|
try {
|
|
2416
2430
|
const channelIdBytes = hexToBytes2(claim.channelId);
|
|
2417
2431
|
const recipientBytes = hexToBytes2(claim.recipient);
|
|
2432
|
+
const verifyingContractBytes = hexToBytes2(verifyingContract);
|
|
2418
2433
|
if (channelIdBytes.length !== 32) {
|
|
2419
2434
|
throw new Error(
|
|
2420
2435
|
`channelId must be 32 bytes (got ${channelIdBytes.length})`
|
|
@@ -2425,11 +2440,18 @@ function recoverEvmSignerAddress(claim) {
|
|
|
2425
2440
|
`recipient must be 20 bytes (got ${recipientBytes.length})`
|
|
2426
2441
|
);
|
|
2427
2442
|
}
|
|
2443
|
+
if (verifyingContractBytes.length !== 20) {
|
|
2444
|
+
throw new Error(
|
|
2445
|
+
`verifyingContract must be 20 bytes (got ${verifyingContractBytes.length})`
|
|
2446
|
+
);
|
|
2447
|
+
}
|
|
2428
2448
|
msgHash = balanceProofHashEvm(
|
|
2429
2449
|
channelIdBytes,
|
|
2430
2450
|
BigInt(claim.cumulativeAmount),
|
|
2431
2451
|
BigInt(claim.nonce),
|
|
2432
|
-
recipientBytes
|
|
2452
|
+
recipientBytes,
|
|
2453
|
+
BigInt(chainId),
|
|
2454
|
+
verifyingContractBytes
|
|
2433
2455
|
);
|
|
2434
2456
|
const sig = secp256k1.Signature.fromBytes(
|
|
2435
2457
|
compactRS,
|
|
@@ -2731,8 +2753,8 @@ function rlpDecodeList(buf) {
|
|
|
2731
2753
|
}
|
|
2732
2754
|
return items;
|
|
2733
2755
|
}
|
|
2734
|
-
function verifyEvmClaimSignature(claim, expectedAddress) {
|
|
2735
|
-
const recovered = recoverEvmSignerAddress(claim);
|
|
2756
|
+
function verifyEvmClaimSignature(claim, expectedAddress, chainId, verifyingContract) {
|
|
2757
|
+
const recovered = recoverEvmSignerAddress(claim, chainId, verifyingContract);
|
|
2736
2758
|
const expected = expectedAddress.toLowerCase();
|
|
2737
2759
|
return {
|
|
2738
2760
|
valid: recovered.toLowerCase() === expected,
|
|
@@ -3098,7 +3120,9 @@ function buildSettlementTx(params) {
|
|
|
3098
3120
|
try {
|
|
3099
3121
|
const { valid, recovered } = verifyEvmClaimSignature(
|
|
3100
3122
|
claim,
|
|
3101
|
-
signer.address
|
|
3123
|
+
signer.address,
|
|
3124
|
+
signer.chainId,
|
|
3125
|
+
signer.contractAddress
|
|
3102
3126
|
);
|
|
3103
3127
|
if (!valid) {
|
|
3104
3128
|
rejected.push({
|
|
@@ -3348,10 +3372,18 @@ function buildSettlementTx(params) {
|
|
|
3348
3372
|
function verifyAccumulatedClaim(claim, signer, minaSignerClient) {
|
|
3349
3373
|
const kind = chainKindOf(claim.pair.to.chain);
|
|
3350
3374
|
if (kind === "evm") {
|
|
3375
|
+
if (typeof signer.chainId !== "number" || !Number.isInteger(signer.chainId) || signer.chainId <= 0 || !signer.contractAddress) {
|
|
3376
|
+
return {
|
|
3377
|
+
valid: false,
|
|
3378
|
+
reason: "INVALID_INPUT: EVM signer requires chainId (positive integer) + contractAddress for the v2 EIP-712 digest (connector#324 finding #1)"
|
|
3379
|
+
};
|
|
3380
|
+
}
|
|
3351
3381
|
try {
|
|
3352
3382
|
const { valid, recovered } = verifyEvmClaimSignature(
|
|
3353
3383
|
claim,
|
|
3354
|
-
signer.address
|
|
3384
|
+
signer.address,
|
|
3385
|
+
signer.chainId,
|
|
3386
|
+
signer.contractAddress
|
|
3355
3387
|
);
|
|
3356
3388
|
if (valid) return { valid: true };
|
|
3357
3389
|
return {
|
|
@@ -3441,6 +3473,7 @@ export {
|
|
|
3441
3473
|
buildSettlementTx,
|
|
3442
3474
|
buildSkillDescriptor,
|
|
3443
3475
|
concatBytes,
|
|
3476
|
+
coopCloseHashEvm,
|
|
3444
3477
|
createArweaveDvmHandler,
|
|
3445
3478
|
createEventStorageHandler,
|
|
3446
3479
|
createHandlerContext,
|
|
@@ -3451,6 +3484,7 @@ export {
|
|
|
3451
3484
|
createSwapHandler,
|
|
3452
3485
|
createVerificationPipeline,
|
|
3453
3486
|
decryptFulfillClaim,
|
|
3487
|
+
eip712DomainSeparatorEvm,
|
|
3454
3488
|
encodeReceiptSigningPayload,
|
|
3455
3489
|
encryptFulfillClaim,
|
|
3456
3490
|
fillEvmSettlementTxGas,
|