@telaro/sacp 1.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/INTEGRATION.md +238 -0
- package/README.md +253 -0
- package/dist/codec.d.ts +35 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +63 -0
- package/dist/codec.js.map +1 -0
- package/dist/constants.d.ts +50 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +50 -0
- package/dist/constants.js.map +1 -0
- package/dist/dispatcher.d.ts +87 -0
- package/dist/dispatcher.d.ts.map +1 -0
- package/dist/dispatcher.js +175 -0
- package/dist/dispatcher.js.map +1 -0
- package/dist/events.d.ts +93 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +142 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/job.d.ts +99 -0
- package/dist/job.d.ts.map +1 -0
- package/dist/job.js +297 -0
- package/dist/job.js.map +1 -0
- package/dist/lst.d.ts +52 -0
- package/dist/lst.d.ts.map +1 -0
- package/dist/lst.js +58 -0
- package/dist/lst.js.map +1 -0
- package/dist/negotiation.d.ts +66 -0
- package/dist/negotiation.d.ts.map +1 -0
- package/dist/negotiation.js +184 -0
- package/dist/negotiation.js.map +1 -0
- package/dist/offering.d.ts +65 -0
- package/dist/offering.d.ts.map +1 -0
- package/dist/offering.js +190 -0
- package/dist/offering.js.map +1 -0
- package/dist/pdas.d.ts +44 -0
- package/dist/pdas.d.ts.map +1 -0
- package/dist/pdas.js +95 -0
- package/dist/pdas.js.map +1 -0
- package/dist/runtime.d.ts +244 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +481 -0
- package/dist/runtime.js.map +1 -0
- package/dist/signer.d.ts +107 -0
- package/dist/signer.d.ts.map +1 -0
- package/dist/signer.js +94 -0
- package/dist/signer.js.map +1 -0
- package/dist/take_rate.d.ts +44 -0
- package/dist/take_rate.d.ts.map +1 -0
- package/dist/take_rate.js +141 -0
- package/dist/take_rate.js.map +1 -0
- package/dist/timeout.d.ts +35 -0
- package/dist/timeout.d.ts.map +1 -0
- package/dist/timeout.js +113 -0
- package/dist/timeout.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +133 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +315 -0
- package/dist/validation.js.map +1 -0
- package/dist/watcher.d.ts +67 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +176 -0
- package/dist/watcher.js.map +1 -0
- package/dist/wormhole.d.ts +88 -0
- package/dist/wormhole.d.ts.map +1 -0
- package/dist/wormhole.js +152 -0
- package/dist/wormhole.js.map +1 -0
- package/package.json +138 -0
package/dist/signer.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Transaction, sendAndConfirmTransaction, } from "@solana/web3.js";
|
|
2
|
+
/** Local-keypair signer. Default for SDK consumers running in-process. */
|
|
3
|
+
export class LocalSigner {
|
|
4
|
+
keypair;
|
|
5
|
+
constructor(keypair) {
|
|
6
|
+
this.keypair = keypair;
|
|
7
|
+
}
|
|
8
|
+
get publicKey() {
|
|
9
|
+
return this.keypair.publicKey;
|
|
10
|
+
}
|
|
11
|
+
async sendAndConfirm(connection, instructions, coSigners = []) {
|
|
12
|
+
const tx = new Transaction().add(...instructions);
|
|
13
|
+
return sendAndConfirmTransaction(connection, tx, [this.keypair, ...coSigners], { commitment: "confirmed" });
|
|
14
|
+
}
|
|
15
|
+
/** Convenience for runtimes that want raw Signer access (e.g. for
|
|
16
|
+
* `@solana/spl-token` helpers that demand `Signer` not just pubkey). */
|
|
17
|
+
asWeb3Signer() {
|
|
18
|
+
return this.keypair;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class RemoteSigner {
|
|
22
|
+
publicKey;
|
|
23
|
+
transport;
|
|
24
|
+
constructor(publicKey, transport) {
|
|
25
|
+
this.publicKey = publicKey;
|
|
26
|
+
this.transport = transport;
|
|
27
|
+
}
|
|
28
|
+
async sendAndConfirm(connection, instructions, coSigners = []) {
|
|
29
|
+
const tx = new Transaction().add(...instructions);
|
|
30
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
31
|
+
tx.recentBlockhash = blockhash;
|
|
32
|
+
tx.lastValidBlockHeight = lastValidBlockHeight;
|
|
33
|
+
tx.feePayer = this.publicKey;
|
|
34
|
+
if (coSigners.length > 0)
|
|
35
|
+
tx.partialSign(...coSigners);
|
|
36
|
+
const message = tx.serializeMessage();
|
|
37
|
+
const signature = await this.transport.signMessage(Uint8Array.from(message));
|
|
38
|
+
tx.addSignature(this.publicKey, Buffer.from(signature));
|
|
39
|
+
const rawTx = tx.serialize();
|
|
40
|
+
const sig = await connection.sendRawTransaction(rawTx, {
|
|
41
|
+
skipPreflight: false,
|
|
42
|
+
preflightCommitment: "confirmed",
|
|
43
|
+
});
|
|
44
|
+
await connection.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, "confirmed");
|
|
45
|
+
return sig;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Browser signer that delegates signing to a connected wallet
|
|
50
|
+
* (Phantom, Backpack, Solflare, anything that follows the
|
|
51
|
+
* `@solana/wallet-adapter-base` `WalletAdapter` interface).
|
|
52
|
+
*
|
|
53
|
+
* Typical Phantom usage:
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* await window.solana.connect();
|
|
57
|
+
* const signer = new WalletAdapterSigner(window.solana);
|
|
58
|
+
* const sacp = new SacpClient({ connection });
|
|
59
|
+
* const session = await sacp.openJob({
|
|
60
|
+
* jobId,
|
|
61
|
+
* actors: { client: signer, provider: ..., evaluator: ... },
|
|
62
|
+
* });
|
|
63
|
+
* await session.fund();
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* Co-signers (ephemeral keypairs) are forwarded to the wallet's
|
|
67
|
+
* `sendTransaction` option. Phantom + Backpack both honor it.
|
|
68
|
+
*/
|
|
69
|
+
export class WalletAdapterSigner {
|
|
70
|
+
adapter;
|
|
71
|
+
constructor(adapter) {
|
|
72
|
+
this.adapter = adapter;
|
|
73
|
+
}
|
|
74
|
+
get publicKey() {
|
|
75
|
+
if (!this.adapter.publicKey) {
|
|
76
|
+
throw new Error("WalletAdapterSigner: wallet not connected (publicKey is null). Call adapter.connect() first.");
|
|
77
|
+
}
|
|
78
|
+
return this.adapter.publicKey;
|
|
79
|
+
}
|
|
80
|
+
async sendAndConfirm(connection, instructions, coSigners = []) {
|
|
81
|
+
const pk = this.publicKey; // throws if not connected
|
|
82
|
+
const tx = new Transaction().add(...instructions);
|
|
83
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
84
|
+
tx.recentBlockhash = blockhash;
|
|
85
|
+
tx.lastValidBlockHeight = lastValidBlockHeight;
|
|
86
|
+
tx.feePayer = pk;
|
|
87
|
+
const sig = await this.adapter.sendTransaction(tx, connection, {
|
|
88
|
+
signers: coSigners,
|
|
89
|
+
});
|
|
90
|
+
await connection.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, "confirmed");
|
|
91
|
+
return sig;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
2
|
+
/** Compute fee from a Provider payout, matching the on-chain math:
|
|
3
|
+
* `floor(amount * bps / 10_000)`. JS bigint avoids the u64 → u128 cast
|
|
4
|
+
* the program does, but the result is identical because we floor. */
|
|
5
|
+
export declare function computeTakeRateFee(amount: bigint, bps: number): bigint;
|
|
6
|
+
/** Treasury ATA for `bondMint`, owned by the Config PDA. Must be
|
|
7
|
+
* pre-initialized (via `createAssociatedTokenAccountIdempotent`) before
|
|
8
|
+
* any Job using `bondMint` can settle on the Provider side. */
|
|
9
|
+
export declare function getTreasuryTokenAccount(bondMint: PublicKey): PublicKey;
|
|
10
|
+
export interface InitConfigParams {
|
|
11
|
+
payer: PublicKey;
|
|
12
|
+
takeRateBps: number;
|
|
13
|
+
authority: PublicKey;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildInitConfigIx(params: InitConfigParams): TransactionInstruction;
|
|
16
|
+
export interface UpdateTakeRateParams {
|
|
17
|
+
authority: PublicKey;
|
|
18
|
+
newBps: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function buildUpdateTakeRateIx(params: UpdateTakeRateParams): TransactionInstruction;
|
|
21
|
+
export interface UpdateValidatorShareParams {
|
|
22
|
+
authority: PublicKey;
|
|
23
|
+
newBps: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function buildUpdateValidatorShareIx(params: UpdateValidatorShareParams): TransactionInstruction;
|
|
26
|
+
export interface SetConfigAuthorityParams {
|
|
27
|
+
authority: PublicKey;
|
|
28
|
+
newAuthority: PublicKey;
|
|
29
|
+
}
|
|
30
|
+
export declare function buildSetConfigAuthorityIx(params: SetConfigAuthorityParams): TransactionInstruction;
|
|
31
|
+
export interface WithdrawTreasuryParams {
|
|
32
|
+
authority: PublicKey;
|
|
33
|
+
bondMint: PublicKey;
|
|
34
|
+
destination: PublicKey;
|
|
35
|
+
amount: bigint;
|
|
36
|
+
}
|
|
37
|
+
export declare function buildWithdrawTreasuryIx(params: WithdrawTreasuryParams): TransactionInstruction;
|
|
38
|
+
export interface FetchedSacpConfig {
|
|
39
|
+
authority: PublicKey;
|
|
40
|
+
takeRateBps: number;
|
|
41
|
+
validatorShareBps: number;
|
|
42
|
+
}
|
|
43
|
+
export declare function fetchSacpConfig(connection: Connection): Promise<FetchedSacpConfig | null>;
|
|
44
|
+
//# sourceMappingURL=take_rate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"take_rate.d.ts","sourceRoot":"","sources":["../src/take_rate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EAET,sBAAsB,EACvB,MAAM,iBAAiB,CAAC;AAiDzB;;qEAEqE;AACrE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQtE;AAED;;+DAE+D;AAC/D,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,CAGtE;AAID,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,gBAAgB,GACvB,sBAAsB,CAqBxB;AAID,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,GAC3B,sBAAsB,CAmBxB;AAID,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,0BAA0B,GACjC,sBAAsB,CAmBxB;AAID,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,SAAS,CAAC;CACzB;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,wBAAwB,GAC/B,sBAAsB,CAcxB;AAID,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,SAAS,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,sBAAsB,GAC7B,sBAAsB,CAmBxB;AAID,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAUnC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { PublicKey, SystemProgram, TransactionInstruction, } from "@solana/web3.js";
|
|
2
|
+
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
|
3
|
+
import { encodeInstruction, encodeU64, } from "./codec.js";
|
|
4
|
+
import { FEE_DENOMINATOR_BPS, MAX_TAKE_RATE_BPS, MAX_VALIDATOR_SHARE_BPS, SACP_PROGRAM_ID, } from "./constants.js";
|
|
5
|
+
import { findSacpConfigPda } from "./pdas.js";
|
|
6
|
+
/**
|
|
7
|
+
* SDK surface for the v0.6 protocol take-rate.
|
|
8
|
+
*
|
|
9
|
+
* The Job program owns one Config PDA (seeds = ["config"]) that holds:
|
|
10
|
+
* - authority: Pubkey that can update the rate, hand off authority,
|
|
11
|
+
* and withdraw from the Treasury.
|
|
12
|
+
* - take_rate_bps: u16 ∈ [0, MAX_TAKE_RATE_BPS] (5%). Applied on
|
|
13
|
+
* every Provider-winning settlement (accept_work +
|
|
14
|
+
* submit_verdict[winner=Provider]). Refund paths (reclaim_escrow,
|
|
15
|
+
* submit_verdict[winner=Client]) pay no fee.
|
|
16
|
+
*
|
|
17
|
+
* Treasury accounting is per-mint. Each accepted bond mint requires a
|
|
18
|
+
* Treasury ATA owned by the Config PDA before the corresponding Job
|
|
19
|
+
* can settle on the Provider side. The SDK exposes
|
|
20
|
+
* `getTreasuryTokenAccount` so callers can derive + `createIdempotent`
|
|
21
|
+
* the ATA in their own setup flow.
|
|
22
|
+
*
|
|
23
|
+
* Encoding follows the same hand-rolled Borsh path as the rest of the
|
|
24
|
+
* SDK (see `codec.ts`) so there is no IDL dependency.
|
|
25
|
+
*/
|
|
26
|
+
const SPL_TOKEN_PROGRAM_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
|
27
|
+
function encodeU16(value) {
|
|
28
|
+
const buf = Buffer.alloc(2);
|
|
29
|
+
buf.writeUInt16LE(value & 0xffff);
|
|
30
|
+
return buf;
|
|
31
|
+
}
|
|
32
|
+
function encodePubkey(value) {
|
|
33
|
+
return Buffer.from(value.toBytes());
|
|
34
|
+
}
|
|
35
|
+
/** Compute fee from a Provider payout, matching the on-chain math:
|
|
36
|
+
* `floor(amount * bps / 10_000)`. JS bigint avoids the u64 → u128 cast
|
|
37
|
+
* the program does, but the result is identical because we floor. */
|
|
38
|
+
export function computeTakeRateFee(amount, bps) {
|
|
39
|
+
if (bps === 0)
|
|
40
|
+
return 0n;
|
|
41
|
+
if (bps < 0 || bps > MAX_TAKE_RATE_BPS) {
|
|
42
|
+
throw new Error(`take rate ${bps} bps out of range [0, ${MAX_TAKE_RATE_BPS}]`);
|
|
43
|
+
}
|
|
44
|
+
return (amount * BigInt(bps)) / BigInt(FEE_DENOMINATOR_BPS);
|
|
45
|
+
}
|
|
46
|
+
/** Treasury ATA for `bondMint`, owned by the Config PDA. Must be
|
|
47
|
+
* pre-initialized (via `createAssociatedTokenAccountIdempotent`) before
|
|
48
|
+
* any Job using `bondMint` can settle on the Provider side. */
|
|
49
|
+
export function getTreasuryTokenAccount(bondMint) {
|
|
50
|
+
const [configPda] = findSacpConfigPda();
|
|
51
|
+
return getAssociatedTokenAddressSync(bondMint, configPda, true);
|
|
52
|
+
}
|
|
53
|
+
export function buildInitConfigIx(params) {
|
|
54
|
+
if (params.takeRateBps < 0 || params.takeRateBps > MAX_TAKE_RATE_BPS) {
|
|
55
|
+
throw new Error(`take rate ${params.takeRateBps} bps out of range [0, ${MAX_TAKE_RATE_BPS}]`);
|
|
56
|
+
}
|
|
57
|
+
const [configPda] = findSacpConfigPda();
|
|
58
|
+
const data = encodeInstruction("init_config", encodeU16(params.takeRateBps), encodePubkey(params.authority));
|
|
59
|
+
return new TransactionInstruction({
|
|
60
|
+
programId: SACP_PROGRAM_ID,
|
|
61
|
+
keys: [
|
|
62
|
+
{ pubkey: params.payer, isSigner: true, isWritable: true },
|
|
63
|
+
{ pubkey: configPda, isSigner: false, isWritable: true },
|
|
64
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
65
|
+
],
|
|
66
|
+
data,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function buildUpdateTakeRateIx(params) {
|
|
70
|
+
if (params.newBps < 0 || params.newBps > MAX_TAKE_RATE_BPS) {
|
|
71
|
+
throw new Error(`take rate ${params.newBps} bps out of range [0, ${MAX_TAKE_RATE_BPS}]`);
|
|
72
|
+
}
|
|
73
|
+
const [configPda] = findSacpConfigPda();
|
|
74
|
+
const data = encodeInstruction("update_take_rate", encodeU16(params.newBps));
|
|
75
|
+
return new TransactionInstruction({
|
|
76
|
+
programId: SACP_PROGRAM_ID,
|
|
77
|
+
keys: [
|
|
78
|
+
{ pubkey: params.authority, isSigner: true, isWritable: false },
|
|
79
|
+
{ pubkey: configPda, isSigner: false, isWritable: true },
|
|
80
|
+
],
|
|
81
|
+
data,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
export function buildUpdateValidatorShareIx(params) {
|
|
85
|
+
if (params.newBps < 0 || params.newBps > MAX_VALIDATOR_SHARE_BPS) {
|
|
86
|
+
throw new Error(`validator share ${params.newBps} bps out of range [0, ${MAX_VALIDATOR_SHARE_BPS}]`);
|
|
87
|
+
}
|
|
88
|
+
const [configPda] = findSacpConfigPda();
|
|
89
|
+
const data = encodeInstruction("update_validator_share", encodeU16(params.newBps));
|
|
90
|
+
return new TransactionInstruction({
|
|
91
|
+
programId: SACP_PROGRAM_ID,
|
|
92
|
+
keys: [
|
|
93
|
+
{ pubkey: params.authority, isSigner: true, isWritable: false },
|
|
94
|
+
{ pubkey: configPda, isSigner: false, isWritable: true },
|
|
95
|
+
],
|
|
96
|
+
data,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export function buildSetConfigAuthorityIx(params) {
|
|
100
|
+
const [configPda] = findSacpConfigPda();
|
|
101
|
+
const data = encodeInstruction("set_config_authority", encodePubkey(params.newAuthority));
|
|
102
|
+
return new TransactionInstruction({
|
|
103
|
+
programId: SACP_PROGRAM_ID,
|
|
104
|
+
keys: [
|
|
105
|
+
{ pubkey: params.authority, isSigner: true, isWritable: false },
|
|
106
|
+
{ pubkey: configPda, isSigner: false, isWritable: true },
|
|
107
|
+
],
|
|
108
|
+
data,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export function buildWithdrawTreasuryIx(params) {
|
|
112
|
+
if (params.amount <= 0n)
|
|
113
|
+
throw new Error("amount must be > 0");
|
|
114
|
+
const [configPda] = findSacpConfigPda();
|
|
115
|
+
const treasuryAta = getTreasuryTokenAccount(params.bondMint);
|
|
116
|
+
const data = encodeInstruction("withdraw_treasury", encodeU64(params.amount));
|
|
117
|
+
return new TransactionInstruction({
|
|
118
|
+
programId: SACP_PROGRAM_ID,
|
|
119
|
+
keys: [
|
|
120
|
+
{ pubkey: params.authority, isSigner: true, isWritable: false },
|
|
121
|
+
{ pubkey: configPda, isSigner: false, isWritable: false },
|
|
122
|
+
{ pubkey: treasuryAta, isSigner: false, isWritable: true },
|
|
123
|
+
{ pubkey: params.destination, isSigner: false, isWritable: true },
|
|
124
|
+
{ pubkey: SPL_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
125
|
+
],
|
|
126
|
+
data,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export async function fetchSacpConfig(connection) {
|
|
130
|
+
const [configPda] = findSacpConfigPda();
|
|
131
|
+
const info = await connection.getAccountInfo(configPda, "confirmed");
|
|
132
|
+
if (!info)
|
|
133
|
+
return null;
|
|
134
|
+
const data = info.data;
|
|
135
|
+
// discriminator(8) | authority(32) | take_rate_bps(2) | validator_share_bps(2) | bump(1)
|
|
136
|
+
const authority = new PublicKey(data.subarray(8, 40));
|
|
137
|
+
const takeRateBps = data.readUInt16LE(40);
|
|
138
|
+
const validatorShareBps = data.readUInt16LE(42);
|
|
139
|
+
return { authority, takeRateBps, validatorShareBps };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=take_rate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"take_rate.js","sourceRoot":"","sources":["../src/take_rate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type FetchedJob } from "./job.js";
|
|
2
|
+
import { SacpClient } from "./runtime.js";
|
|
3
|
+
import type { SacpSigner } from "./signer.js";
|
|
4
|
+
export interface ReclaimWatcherOptions {
|
|
5
|
+
client: SacpClient;
|
|
6
|
+
/** Buyer signer. Watcher only reclaims Jobs whose `client` field
|
|
7
|
+
* matches this pubkey. */
|
|
8
|
+
signer: SacpSigner;
|
|
9
|
+
/** Poll interval. Defaults to 30 seconds — Jobs don't usually
|
|
10
|
+
* expire on the second. */
|
|
11
|
+
pollIntervalMs?: number;
|
|
12
|
+
/** Optional safety margin in seconds added to `submit_deadline`
|
|
13
|
+
* before reclaiming, to allow for clock skew between the user's
|
|
14
|
+
* box and the cluster. Defaults to 30 s. */
|
|
15
|
+
graceSecs?: number;
|
|
16
|
+
/** Fired before each reclaim attempt. Throw to skip this Job (it
|
|
17
|
+
* stays eligible on the next tick). */
|
|
18
|
+
beforeReclaim?: (job: FetchedJob) => void | Promise<void>;
|
|
19
|
+
/** Fired after a successful reclaim tx. */
|
|
20
|
+
onReclaimed?: (job: FetchedJob, signature: string) => void | Promise<void>;
|
|
21
|
+
logger?: {
|
|
22
|
+
info: (m: string) => void;
|
|
23
|
+
error: (m: string, e?: unknown) => void;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export declare class ReclaimWatcher {
|
|
27
|
+
private readonly opts;
|
|
28
|
+
private timer;
|
|
29
|
+
private inFlight;
|
|
30
|
+
constructor(opts: ReclaimWatcherOptions);
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
stop(): void;
|
|
33
|
+
private tick;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../src/timeout.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAc,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0B9C,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB;8BAC0B;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB;+BAC2B;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;gDAE4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;2CACuC;IACvC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,2CAA2C;IAC3C,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAC1B,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KACzC,CAAC;CACH;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAGG;IACxB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAqB;gBAEzB,IAAI,EAAE,qBAAqB;IAQjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,IAAI,IAAI,IAAI;YAOE,IAAI;CA4BnB"}
|
package/dist/timeout.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { SACP_PROGRAM_ID } from "./constants.js";
|
|
2
|
+
import { parseJobFromBuffer, buildReclaimEscrowIx, } from "./job.js";
|
|
3
|
+
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
|
4
|
+
/**
|
|
5
|
+
* v0.9 Phase 5 — Timeout enforcement helper.
|
|
6
|
+
*
|
|
7
|
+
* `ReclaimWatcher` is a client-side daemon that scans for `Funded`
|
|
8
|
+
* Jobs whose client matches the supplied signer and whose
|
|
9
|
+
* `submit_deadline` has elapsed, then issues `reclaim_escrow` on
|
|
10
|
+
* each. It exists because forgetting to reclaim is the #1 way a
|
|
11
|
+
* buyer leaves money sitting in escrow.
|
|
12
|
+
*
|
|
13
|
+
* Why client-side, not a program-side crank: `reclaim_escrow`
|
|
14
|
+
* already gates on `client` signing, so anyone-callable auto-reclaim
|
|
15
|
+
* would need a program change (Phase 7+). The watcher is the cheap
|
|
16
|
+
* win that ships today; the program-side crank can replace it later
|
|
17
|
+
* without breaking this API.
|
|
18
|
+
*
|
|
19
|
+
* Offset reused from the watcher module:
|
|
20
|
+
* Job discriminator(8) | job_id(8) | client(32) — so the client
|
|
21
|
+
* pubkey sits at offset 16.
|
|
22
|
+
*/
|
|
23
|
+
const CLIENT_OFFSET = 16;
|
|
24
|
+
export class ReclaimWatcher {
|
|
25
|
+
opts;
|
|
26
|
+
timer = null;
|
|
27
|
+
inFlight = new Set();
|
|
28
|
+
constructor(opts) {
|
|
29
|
+
this.opts = {
|
|
30
|
+
pollIntervalMs: 30_000,
|
|
31
|
+
graceSecs: 30,
|
|
32
|
+
...opts,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async start() {
|
|
36
|
+
if (this.timer)
|
|
37
|
+
return;
|
|
38
|
+
await this.tick();
|
|
39
|
+
this.timer = setInterval(() => void this.tick(), this.opts.pollIntervalMs);
|
|
40
|
+
}
|
|
41
|
+
stop() {
|
|
42
|
+
if (this.timer) {
|
|
43
|
+
clearInterval(this.timer);
|
|
44
|
+
this.timer = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async tick() {
|
|
48
|
+
const { client, signer, graceSecs, beforeReclaim, onReclaimed, logger } = this.opts;
|
|
49
|
+
try {
|
|
50
|
+
const expired = await findExpiredJobsForClient(client.connection, signer.publicKey, graceSecs ?? 30);
|
|
51
|
+
for (const job of expired) {
|
|
52
|
+
const key = `${job.jobId}`;
|
|
53
|
+
if (this.inFlight.has(key))
|
|
54
|
+
continue;
|
|
55
|
+
this.inFlight.add(key);
|
|
56
|
+
try {
|
|
57
|
+
if (beforeReclaim)
|
|
58
|
+
await beforeReclaim(job);
|
|
59
|
+
const sig = await reclaim(client, signer, job);
|
|
60
|
+
if (onReclaimed)
|
|
61
|
+
await onReclaimed(job, sig);
|
|
62
|
+
logger?.info?.(`reclaimed ${job.jobId} (sig ${sig})`);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
logger?.error(`reclaim failed for job ${job.jobId}`, e);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
this.inFlight.delete(key);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
logger?.error("ReclaimWatcher tick failed", e);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Internal: list Funded Jobs whose client matches `actor` and whose
|
|
78
|
+
* deadline has passed (with `graceSecs` buffer). */
|
|
79
|
+
async function findExpiredJobsForClient(conn, actor, graceSecs) {
|
|
80
|
+
const accounts = await conn.getProgramAccounts(SACP_PROGRAM_ID, {
|
|
81
|
+
commitment: "confirmed",
|
|
82
|
+
filters: [
|
|
83
|
+
{ memcmp: { offset: CLIENT_OFFSET, bytes: actor.toBase58() } },
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
const now = Math.floor(Date.now() / 1000);
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const { account } of accounts) {
|
|
89
|
+
try {
|
|
90
|
+
const job = parseJobFromBuffer(account.data);
|
|
91
|
+
if (job.state !== "Funded")
|
|
92
|
+
continue;
|
|
93
|
+
const deadline = Number(job.submitDeadline);
|
|
94
|
+
if (now < deadline + graceSecs)
|
|
95
|
+
continue;
|
|
96
|
+
out.push(job);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Not a Job — skip.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
async function reclaim(client, signer, job) {
|
|
105
|
+
const clientAta = getAssociatedTokenAddressSync(job.bondMint, signer.publicKey);
|
|
106
|
+
const ix = buildReclaimEscrowIx({
|
|
107
|
+
client: signer.publicKey,
|
|
108
|
+
jobId: job.jobId,
|
|
109
|
+
clientTokenAccount: clientAta,
|
|
110
|
+
});
|
|
111
|
+
return signer.sendAndConfirm(client.connection, [ix]);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=timeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeout.js","sourceRoot":"","sources":["../src/timeout.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PublicKey } from "@solana/web3.js";
|
|
2
|
+
/**
|
|
3
|
+
* Job state machine, matching SRFC v0.1 §"Part A — State machine".
|
|
4
|
+
* Encoded on-chain as a u8 discriminator; the SDK exposes a string
|
|
5
|
+
* union for ergonomics.
|
|
6
|
+
*/
|
|
7
|
+
export type JobState = "Open" | "Funded" | "Submitted" | "Disputed" | "Settled";
|
|
8
|
+
/** Numeric encoding used by the Anchor program. Mirrors the on-chain enum. */
|
|
9
|
+
export declare const JOB_STATE_NUMERIC: Record<JobState, number>;
|
|
10
|
+
/**
|
|
11
|
+
* Roles defined by sACP. `evaluator` is optional in v0.1 — if absent,
|
|
12
|
+
* the Job falls back to client-driven auto-settle on submit timeout.
|
|
13
|
+
*
|
|
14
|
+
* Spec note: the evaluator can be either a plain Pubkey (single signer
|
|
15
|
+
* or multisig PDA) or a Validator PDA from the Part B registry. Both
|
|
16
|
+
* resolve to a `Pubkey` from the SDK's perspective; the on-chain
|
|
17
|
+
* verdict path checks whether the signer matches a registered
|
|
18
|
+
* Validator and gates accordingly.
|
|
19
|
+
*/
|
|
20
|
+
export interface JobRoles {
|
|
21
|
+
client: PublicKey;
|
|
22
|
+
provider: PublicKey;
|
|
23
|
+
evaluator?: PublicKey;
|
|
24
|
+
}
|
|
25
|
+
/** Verdict outcomes recorded on-chain after dispute resolution. */
|
|
26
|
+
export type VerdictWinner = "Client" | "Provider";
|
|
27
|
+
export declare const VERDICT_WINNER_NUMERIC: Record<VerdictWinner, number>;
|
|
28
|
+
/**
|
|
29
|
+
* Information returned to a caller after `create_job` succeeds. The
|
|
30
|
+
* Job PDA is deterministic from `(seed prefix, jobId)`, so callers
|
|
31
|
+
* holding `jobId` can re-derive `jobPda` later without storing it.
|
|
32
|
+
*/
|
|
33
|
+
export interface CreateJobResult {
|
|
34
|
+
jobId: bigint;
|
|
35
|
+
jobPda: PublicKey;
|
|
36
|
+
escrowPda: PublicKey;
|
|
37
|
+
txSignature: string;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEhF,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAMtD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;AAElD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAGhE,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Numeric encoding used by the Anchor program. Mirrors the on-chain enum. */
|
|
2
|
+
export const JOB_STATE_NUMERIC = {
|
|
3
|
+
Open: 0,
|
|
4
|
+
Funded: 1,
|
|
5
|
+
Submitted: 2,
|
|
6
|
+
Disputed: 3,
|
|
7
|
+
Settled: 4,
|
|
8
|
+
};
|
|
9
|
+
export const VERDICT_WINNER_NUMERIC = {
|
|
10
|
+
Client: 0,
|
|
11
|
+
Provider: 1,
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AASA,8EAA8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAA6B;IACzD,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;CACX,CAAC;AAqBF,MAAM,CAAC,MAAM,sBAAsB,GAAkC;IACnE,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;CACZ,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Connection, PublicKey, TransactionInstruction, type Signer } from "@solana/web3.js";
|
|
2
|
+
import { findBondAuthorityPda, findBondVaultPda, findChallengePda, findValidatorPda } from "./pdas.js";
|
|
3
|
+
import type { VerdictWinner } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Permissionless treasury vault bootstrap (one per bond mint).
|
|
6
|
+
* Anyone can pay rent; the vault is owned by a program PDA so funds
|
|
7
|
+
* can only be moved by a future governance instruction.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildInitTreasuryVaultIx(payer: PublicKey, bondMint: PublicKey): {
|
|
10
|
+
ix: TransactionInstruction;
|
|
11
|
+
treasuryVaultPda: PublicKey;
|
|
12
|
+
};
|
|
13
|
+
export interface RegisterValidatorParams {
|
|
14
|
+
authority: PublicKey;
|
|
15
|
+
/** SPL Token mint pinned to this validator. Can't be changed later. */
|
|
16
|
+
bondMint: PublicKey;
|
|
17
|
+
/** Off-chain operator info / SLA URI. */
|
|
18
|
+
metadataUri: string;
|
|
19
|
+
}
|
|
20
|
+
export interface RegisterValidatorBuildResult {
|
|
21
|
+
ix: TransactionInstruction;
|
|
22
|
+
validatorPda: PublicKey;
|
|
23
|
+
bondAuthorityPda: PublicKey;
|
|
24
|
+
bondVaultPda: PublicKey;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildRegisterValidatorIx(params: RegisterValidatorParams): RegisterValidatorBuildResult;
|
|
27
|
+
export interface StakeBondParams {
|
|
28
|
+
authority: PublicKey;
|
|
29
|
+
amount: bigint;
|
|
30
|
+
operatorTokenAccount: PublicKey;
|
|
31
|
+
}
|
|
32
|
+
export declare function buildStakeBondIx(params: StakeBondParams): TransactionInstruction;
|
|
33
|
+
export declare function buildAcceptVerdictIx(authority: PublicKey, jobId: bigint, winner: VerdictWinner): TransactionInstruction;
|
|
34
|
+
/**
|
|
35
|
+
* Full CPI bridge — the Validator PDA calls sacp_job::submit_verdict
|
|
36
|
+
* directly. The Job must have been created with
|
|
37
|
+
* `evaluator = validatorPda` for the sacp_job has_one check to pass.
|
|
38
|
+
*
|
|
39
|
+
* This is the bond-collateralized verdict path. Unlike
|
|
40
|
+
* `buildAcceptVerdictIx` (event-only), this one actually moves money:
|
|
41
|
+
* escrow drains to the chosen winner in the same transaction.
|
|
42
|
+
*/
|
|
43
|
+
export interface IssueVerdictParams {
|
|
44
|
+
authority: PublicKey;
|
|
45
|
+
client: PublicKey;
|
|
46
|
+
provider: PublicKey;
|
|
47
|
+
jobId: bigint;
|
|
48
|
+
bondMint: PublicKey;
|
|
49
|
+
winner: VerdictWinner;
|
|
50
|
+
clientTokenAccount: PublicKey;
|
|
51
|
+
providerTokenAccount: PublicKey;
|
|
52
|
+
/** v0.7+. Validator PDA's off-curve ATA on bondMint. SDK consumers
|
|
53
|
+
* should derive with
|
|
54
|
+
* `getAssociatedTokenAddressSync(bondMint, validatorPda, true)`
|
|
55
|
+
* and call `createAssociatedTokenAccountIdempotent` with
|
|
56
|
+
* `allowOwnerOffCurve=true` before any settlement. */
|
|
57
|
+
validatorTokenAccount: PublicKey;
|
|
58
|
+
}
|
|
59
|
+
export declare function buildIssueVerdictIx(params: IssueVerdictParams): TransactionInstruction;
|
|
60
|
+
export interface ChallengeVerdictParams {
|
|
61
|
+
challenger: PublicKey;
|
|
62
|
+
validatorAuthority: PublicKey;
|
|
63
|
+
jobId: bigint;
|
|
64
|
+
evidenceUri: string;
|
|
65
|
+
}
|
|
66
|
+
export declare function buildChallengeVerdictIx(params: ChallengeVerdictParams): {
|
|
67
|
+
ix: TransactionInstruction;
|
|
68
|
+
challengePda: PublicKey;
|
|
69
|
+
};
|
|
70
|
+
export interface ResolveChallengeParams {
|
|
71
|
+
authority: PublicKey;
|
|
72
|
+
validatorAuthority: PublicKey;
|
|
73
|
+
/** The bond mint pinned at register_validator time. */
|
|
74
|
+
bondMint: PublicKey;
|
|
75
|
+
jobId: bigint;
|
|
76
|
+
slash: boolean;
|
|
77
|
+
/** Required when slash=true; ignored otherwise. */
|
|
78
|
+
challengerTokenAccount: PublicKey;
|
|
79
|
+
}
|
|
80
|
+
export declare function buildResolveChallengeIx(params: ResolveChallengeParams): TransactionInstruction;
|
|
81
|
+
export declare function buildInitResolverConfigIx(params: {
|
|
82
|
+
payer: PublicKey;
|
|
83
|
+
authority: PublicKey;
|
|
84
|
+
}): TransactionInstruction;
|
|
85
|
+
export declare function buildSetResolverAuthorityIx(params: {
|
|
86
|
+
authority: PublicKey;
|
|
87
|
+
newAuthority: PublicKey;
|
|
88
|
+
}): TransactionInstruction;
|
|
89
|
+
export interface FetchedResolverConfig {
|
|
90
|
+
authority: PublicKey;
|
|
91
|
+
}
|
|
92
|
+
export declare function fetchResolverConfig(connection: Connection): Promise<FetchedResolverConfig | null>;
|
|
93
|
+
export interface WithdrawBondParams {
|
|
94
|
+
authority: PublicKey;
|
|
95
|
+
amount: bigint;
|
|
96
|
+
operatorTokenAccount: PublicKey;
|
|
97
|
+
}
|
|
98
|
+
export declare function buildWithdrawBondIx(params: WithdrawBondParams): TransactionInstruction;
|
|
99
|
+
export declare function registerValidator(connection: Connection, operator: Signer, params: {
|
|
100
|
+
bondMint: PublicKey;
|
|
101
|
+
metadataUri: string;
|
|
102
|
+
}): Promise<{
|
|
103
|
+
validatorPda: PublicKey;
|
|
104
|
+
bondVaultPda: PublicKey;
|
|
105
|
+
txSignature: string;
|
|
106
|
+
}>;
|
|
107
|
+
export interface FetchedValidator {
|
|
108
|
+
authority: PublicKey;
|
|
109
|
+
metadataUri: string;
|
|
110
|
+
bondMint: PublicKey;
|
|
111
|
+
bondAmount: bigint;
|
|
112
|
+
slashCount: number;
|
|
113
|
+
activeChallenges: number;
|
|
114
|
+
registeredAt: bigint;
|
|
115
|
+
/** v0.9 Phase 7 reputation counters. Defaults to 0 on pre-v0.9
|
|
116
|
+
* Validator accounts (which serialize shorter, so the parse stops
|
|
117
|
+
* before these fields and we fill in 0). */
|
|
118
|
+
successfulSettles: number;
|
|
119
|
+
failedChallenges: number;
|
|
120
|
+
wonChallenges: number;
|
|
121
|
+
}
|
|
122
|
+
export declare function fetchValidator(connection: Connection, authority: PublicKey): Promise<FetchedValidator | null>;
|
|
123
|
+
export interface FetchedChallenge {
|
|
124
|
+
jobId: bigint;
|
|
125
|
+
challenger: PublicKey;
|
|
126
|
+
validator: PublicKey;
|
|
127
|
+
evidenceUri: string;
|
|
128
|
+
filedAt: bigint;
|
|
129
|
+
resolved: boolean;
|
|
130
|
+
}
|
|
131
|
+
export declare function fetchChallenge(connection: Connection, jobId: bigint): Promise<FetchedChallenge | null>;
|
|
132
|
+
export { findBondAuthorityPda, findBondVaultPda, findChallengePda, findValidatorPda, };
|
|
133
|
+
//# sourceMappingURL=validation.d.ts.map
|