@infantmen-labs/harbor-sdk 0.6.0 → 0.7.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 +36 -3
- package/dist/src/adjudicate.d.ts +11 -0
- package/dist/src/adjudicate.js +11 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/receipt.d.ts +6 -2
- package/dist/src/receipt.js +8 -3
- package/dist/test/vectors.test.js +9 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# harbor-sdk
|
|
1
|
+
# @infantmen-labs/harbor-sdk
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for Harbor bonded refunds on Solana: PDA helpers,
|
|
4
4
|
instruction builders, receipt codec, ed25519 verify, account decoders.
|
|
@@ -28,8 +28,9 @@ const ok = verifyEd25519(signer, receiptMessageBytes(receipt), signature);
|
|
|
28
28
|
|
|
29
29
|
What it covers: `bondPda` / `bindingPda` / `disputePda` / `receiptPda` /
|
|
30
30
|
`treasuryPda` / `claimPda`, instruction builders for all 11 program
|
|
31
|
-
entrypoints, the
|
|
32
|
-
|
|
31
|
+
entrypoints, the receipt-v1 layout (249 bytes; `mint` + `programId`
|
|
32
|
+
domain separators appended — all v0 offsets unchanged), voucher bytes,
|
|
33
|
+
and zero-dependency account decoders. See `examples/bond-watch` for a
|
|
33
34
|
complete third-party monitor built on SDK + web3.js only.
|
|
34
35
|
|
|
35
36
|
## Buyer patterns (demand-side integration)
|
|
@@ -56,3 +57,35 @@ The proven demand-side flow:
|
|
|
56
57
|
4. **Resolve via any live keeper.** Any keeper watching the program
|
|
57
58
|
resolves matured disputes; verify onchain (dispute account closed,
|
|
58
59
|
claimant +95%). Operate your own for production (see keeper README).
|
|
60
|
+
|
|
61
|
+
## Live devnet endpoints
|
|
62
|
+
|
|
63
|
+
All on Solana devnet, live today — the docs site exposes the demo
|
|
64
|
+
merchant at its own /api (see harbor-orch.vercel.app/docs):
|
|
65
|
+
|
|
66
|
+
| What | Address |
|
|
67
|
+
|---|---|
|
|
68
|
+
| Harbor program | BuRyKLqCsTLcyLVFEjxTjmF4DryCT3LmVDjwqhduvB4H |
|
|
69
|
+
| Channels program | CHNLxYvVA28MJP9PrFuDXccuoGXAx7jBacfLEkahyGsX |
|
|
70
|
+
| tUSDC mint | HDwpthFfTBi4YyGo1zgd7zxyonE5CZsCizpVqURHGD54 |
|
|
71
|
+
| Demo merchant | GQyf8wvGfpaLZvfvbXonpdiEfAGRvRXz2P6PkWxQ4rLJ |
|
|
72
|
+
| Demo bond | 2G19xBTWXTYM8y6rQCs9ucMkQr36RDX1FucMf22jFLuP |
|
|
73
|
+
|
|
74
|
+
Devnet tUSDC for testing: POST https://harbor-orch.vercel.app/api/faucet
|
|
75
|
+
with {"address":"<wallet>"} — 50 per drip, 100 lifetime per address,
|
|
76
|
+
5/day per IP (the mint is closed, so this spends a funded pot).
|
|
77
|
+
|
|
78
|
+
## Receipt v1 migration (from 0.4.x)
|
|
79
|
+
|
|
80
|
+
receiptMessageBytes now requires two extra fields — mint and programId —
|
|
81
|
+
appended after signer (249 bytes total; every v0 offset unchanged).
|
|
82
|
+
Verification of a v0 receipt fails against the deployed v1 program by
|
|
83
|
+
construction, so migrate when you upgrade. Full layout:
|
|
84
|
+
docs/receipt-schema-v1.md in the repo.
|
|
85
|
+
|
|
86
|
+
## Docs
|
|
87
|
+
|
|
88
|
+
- Repo: https://github.com/infantmen-labs/harbor
|
|
89
|
+
- Buyer quickstart + live endpoints: docs/buyer-quickstart.md (repo)
|
|
90
|
+
- On-site integration guide: https://harbor-orch.vercel.app/docs
|
|
91
|
+
- Proof bundle (every claim explorer-clickable): docs/proof-bundle.md (repo)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Dispute } from "./accounts";
|
|
2
|
+
export type Action = {
|
|
3
|
+
kind: "resolve-timeout";
|
|
4
|
+
} | {
|
|
5
|
+
kind: "pending";
|
|
6
|
+
why: string;
|
|
7
|
+
};
|
|
8
|
+
/** Pure adjudication: every matured dispute resolves as a timeout refund.
|
|
9
|
+
* There is no delivered path — receipts are merchant-signed liveness
|
|
10
|
+
* attestations, never evidence against a claim. */
|
|
11
|
+
export declare function decide(d: Dispute, slot: bigint): Action;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decide = decide;
|
|
4
|
+
/** Pure adjudication: every matured dispute resolves as a timeout refund.
|
|
5
|
+
* There is no delivered path — receipts are merchant-signed liveness
|
|
6
|
+
* attestations, never evidence against a claim. */
|
|
7
|
+
function decide(d, slot) {
|
|
8
|
+
if (slot > d.deadlineSlot)
|
|
9
|
+
return { kind: "resolve-timeout" };
|
|
10
|
+
return { kind: "pending", why: "within challenge window" };
|
|
11
|
+
}
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -22,6 +22,7 @@ __exportStar(require("./tx"), exports);
|
|
|
22
22
|
__exportStar(require("./u64"), exports);
|
|
23
23
|
__exportStar(require("./channels"), exports);
|
|
24
24
|
__exportStar(require("./buyer"), exports);
|
|
25
|
+
__exportStar(require("./adjudicate"), exports);
|
|
25
26
|
__exportStar(require("./ed25519"), exports);
|
|
26
27
|
__exportStar(require("./verify"), exports);
|
|
27
28
|
__exportStar(require("./harbor-ix"), exports);
|
package/dist/src/receipt.d.ts
CHANGED
|
@@ -9,12 +9,16 @@ export interface ReceiptFields {
|
|
|
9
9
|
nonce: bigint;
|
|
10
10
|
expirySlot: bigint;
|
|
11
11
|
signer: PublicKey;
|
|
12
|
+
/** v1 domain separators (appended — every v0 offset unchanged). */
|
|
13
|
+
mint: PublicKey;
|
|
14
|
+
programId: PublicKey;
|
|
12
15
|
}
|
|
13
16
|
/** Borsh encoding of the onchain ReceiptMessage. Field order is consensus. */
|
|
14
17
|
export declare function receiptMessageBytes(f: ReceiptFields): Buffer;
|
|
15
|
-
export declare const RECEIPT_MESSAGE_LEN =
|
|
18
|
+
export declare const RECEIPT_MESSAGE_LEN = 249;
|
|
16
19
|
/**
|
|
17
|
-
* Byte offset of expirySlot in the
|
|
20
|
+
* Byte offset of expirySlot in the 249-byte receipt message (unchanged
|
|
21
|
+
* from v0 — domain separators were appended after signer)
|
|
18
22
|
* (merchant 32 | binding 32 | cumulative 8 | meter 32 | output 32 |
|
|
19
23
|
* status 1 | nonce 8 | expiry 8 | signer 32).
|
|
20
24
|
*/
|
package/dist/src/receipt.js
CHANGED
|
@@ -13,7 +13,7 @@ function assertLen(b, n, name) {
|
|
|
13
13
|
function receiptMessageBytes(f) {
|
|
14
14
|
assertLen(f.meterHash, 32, "meterHash");
|
|
15
15
|
assertLen(f.outputHash, 32, "outputHash");
|
|
16
|
-
const out = Buffer.alloc(
|
|
16
|
+
const out = Buffer.alloc(249);
|
|
17
17
|
let o = 0;
|
|
18
18
|
f.merchant.toBuffer().copy(out, o);
|
|
19
19
|
o += 32;
|
|
@@ -33,11 +33,16 @@ function receiptMessageBytes(f) {
|
|
|
33
33
|
o += 8;
|
|
34
34
|
f.signer.toBuffer().copy(out, o);
|
|
35
35
|
o += 32;
|
|
36
|
+
f.mint.toBuffer().copy(out, o);
|
|
37
|
+
o += 32;
|
|
38
|
+
f.programId.toBuffer().copy(out, o);
|
|
39
|
+
o += 32;
|
|
36
40
|
return out;
|
|
37
41
|
}
|
|
38
|
-
exports.RECEIPT_MESSAGE_LEN =
|
|
42
|
+
exports.RECEIPT_MESSAGE_LEN = 249;
|
|
39
43
|
/**
|
|
40
|
-
* Byte offset of expirySlot in the
|
|
44
|
+
* Byte offset of expirySlot in the 249-byte receipt message (unchanged
|
|
45
|
+
* from v0 — domain separators were appended after signer)
|
|
41
46
|
* (merchant 32 | binding 32 | cumulative 8 | meter 32 | output 32 |
|
|
42
47
|
* status 1 | nonce 8 | expiry 8 | signer 32).
|
|
43
48
|
*/
|
|
@@ -21,6 +21,8 @@ const P = (n) => new web3_js_1.PublicKey(Buffer.alloc(32, n));
|
|
|
21
21
|
nonce: 7n,
|
|
22
22
|
expirySlot: 999n,
|
|
23
23
|
signer: P(1),
|
|
24
|
+
mint: P(5),
|
|
25
|
+
programId: P(6),
|
|
24
26
|
};
|
|
25
27
|
const got = (0, index_1.receiptMessageBytes)(f);
|
|
26
28
|
strict_1.default.equal(got.length, index_1.RECEIPT_MESSAGE_LEN);
|
|
@@ -47,6 +49,9 @@ const P = (n) => new web3_js_1.PublicKey(Buffer.alloc(32, n));
|
|
|
47
49
|
return b;
|
|
48
50
|
})(),
|
|
49
51
|
Buffer.alloc(32, 1),
|
|
52
|
+
// v1 domain separators (appended — v0 prefix above unchanged).
|
|
53
|
+
Buffer.alloc(32, 5),
|
|
54
|
+
Buffer.alloc(32, 6),
|
|
50
55
|
]);
|
|
51
56
|
strict_1.default.ok(got.equals(exp));
|
|
52
57
|
});
|
|
@@ -62,6 +67,8 @@ const P = (n) => new web3_js_1.PublicKey(Buffer.alloc(32, n));
|
|
|
62
67
|
nonce: 1n,
|
|
63
68
|
expirySlot: 100n,
|
|
64
69
|
signer: new web3_js_1.PublicKey(kp.publicKey),
|
|
70
|
+
mint: P(5),
|
|
71
|
+
programId: P(6),
|
|
65
72
|
});
|
|
66
73
|
const sig = (0, index_1.signEd25519)(kp.secretKey, msg);
|
|
67
74
|
strict_1.default.ok((0, index_1.verifyEd25519)(new web3_js_1.PublicKey(kp.publicKey), msg, sig));
|
|
@@ -483,6 +490,8 @@ const P = (n) => new web3_js_1.PublicKey(Buffer.alloc(32, n));
|
|
|
483
490
|
nonce: 7n,
|
|
484
491
|
expirySlot: 999n,
|
|
485
492
|
signer: P(1),
|
|
493
|
+
mint: P(5),
|
|
494
|
+
programId: P(6),
|
|
486
495
|
};
|
|
487
496
|
(0, node_test_1.it)("reads back the encoded expiry slot", () => {
|
|
488
497
|
const msg = (0, index_1.receiptMessageBytes)(F);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infantmen-labs/harbor-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "TypeScript SDK for Harbor bonded refunds on Solana: PDA helpers, instruction builders, receipt codec, ed25519 verify, account decoders.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"anchor"
|
|
12
12
|
],
|
|
13
13
|
"files": [
|
|
14
|
-
"dist"
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"main": "dist/src/index.js",
|
|
17
18
|
"types": "dist/src/index.d.ts",
|