descro playgound & sdk

This commit is contained in:
thesn10
2026-05-18 22:02:41 +02:00
parent 84a2ec4200
commit 2a89352212
37 changed files with 8775 additions and 12088 deletions

16
sdk/package.json Normal file
View File

@@ -0,0 +1,16 @@
{
"name": "@descro/sdk",
"version": "0.1.0",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"dependencies": {
"@coral-xyz/anchor": "^0.32.1",
"@solana/web3.js": "^1.98.4",
"bn.js": "^5.2.1"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"typescript": "^6.0.3"
}
}

198
sdk/src/escrow.ts Normal file
View File

@@ -0,0 +1,198 @@
import {
PublicKey,
SystemProgram,
TransactionInstruction,
} from "@solana/web3.js";
import { AnchorProvider, Program, BN } from "@coral-xyz/anchor";
import type { Idl } from "@coral-xyz/anchor";
import descroIdl from "./idl/descro.json";
import {
ESCROW_PROGRAM_ID,
REGISTRY_PROGRAM_ID,
deriveEscrowPda,
deriveVaultPda,
deriveEscrowAuthorityPda,
deriveResolverEntryPda,
} from "./pda";
import type { EscrowAccount, EscrowAccountWithPda, Winner } from "./types";
export class EscrowClient {
readonly program: Program;
readonly provider: AnchorProvider;
constructor(provider: AnchorProvider) {
this.provider = provider;
this.program = new Program(
descroIdl as Idl,
new PublicKey(ESCROW_PROGRAM_ID),
provider
);
}
async buildCreateEscrow(params: {
seller: PublicKey;
buyer: PublicKey;
amount: BN;
disputeResolver: PublicKey | null;
escrowId: BN;
}): Promise<TransactionInstruction> {
const { seller, buyer, amount, disputeResolver, escrowId } = params;
const [escrowPda] = deriveEscrowPda(seller, escrowId);
const [vaultPda] = deriveVaultPda(escrowPda);
return await (this.program.methods as any)
.createEscrow(amount, disputeResolver, escrowId)
.accounts({
seller,
buyer,
escrowAccount: escrowPda,
vault: vaultPda,
systemProgram: SystemProgram.programId,
})
.instruction();
}
async buildDeposit(params: {
buyer: PublicKey;
escrowPda: PublicKey;
}): Promise<TransactionInstruction> {
const { buyer, escrowPda } = params;
const [vaultPda] = deriveVaultPda(escrowPda);
return await (this.program.methods as any)
.deposit()
.accounts({
buyer,
escrowAccount: escrowPda,
vault: vaultPda,
systemProgram: SystemProgram.programId,
})
.instruction();
}
async buildComplete(params: {
buyer: PublicKey;
seller: PublicKey;
escrowPda: PublicKey;
}): Promise<TransactionInstruction> {
const { buyer, seller, escrowPda } = params;
const [vaultPda] = deriveVaultPda(escrowPda);
return await (this.program.methods as any)
.complete()
.accounts({
buyer,
seller,
escrowAccount: escrowPda,
vault: vaultPda,
systemProgram: SystemProgram.programId,
})
.instruction();
}
async buildDispute(params: {
initiator: PublicKey;
escrowPda: PublicKey;
}): Promise<TransactionInstruction> {
const { initiator, escrowPda } = params;
return await (this.program.methods as any)
.dispute()
.accounts({
initiator,
escrowAccount: escrowPda,
})
.instruction();
}
async buildCancel(params: {
seller: PublicKey;
escrowPda: PublicKey;
}): Promise<TransactionInstruction> {
const { seller, escrowPda } = params;
return await (this.program.methods as any)
.cancel()
.accounts({
seller,
escrowAccount: escrowPda,
systemProgram: SystemProgram.programId,
})
.instruction();
}
async buildResolve(params: {
resolver: PublicKey;
winner: "buyer" | "seller";
winnerPubkey: PublicKey;
seller: PublicKey;
escrowPda: PublicKey;
disputeResolver: PublicKey | null;
}): Promise<TransactionInstruction> {
const { resolver, winner, winnerPubkey, seller, escrowPda, disputeResolver } = params;
const [vaultPda] = deriveVaultPda(escrowPda);
const [escrowAuthority] = deriveEscrowAuthorityPda();
const registryProgram = disputeResolver ? REGISTRY_PROGRAM_ID : SystemProgram.programId;
const resolverEntryAuthority = disputeResolver ?? resolver;
const [resolverEntry] = deriveResolverEntryPda(resolverEntryAuthority);
const winnerArg: Winner =
winner === "buyer" ? { buyer: {} } : { seller: {} };
return await (this.program.methods as any)
.resolve(winnerArg)
.accounts({
resolver,
winner: winnerPubkey,
seller,
escrowAccount: escrowPda,
vault: vaultPda,
resolverEntry,
escrowAuthority,
registryProgram,
systemProgram: SystemProgram.programId,
})
.instruction();
}
async fetchEscrow(pda: PublicKey): Promise<EscrowAccount | null> {
try {
const raw = await (this.program.account as any).escrowAccount.fetch(pda);
return raw as EscrowAccount;
} catch {
return null;
}
}
async fetchAllEscrows(): Promise<EscrowAccountWithPda[]> {
const accounts = await (this.program.account as any).escrowAccount.all();
return accounts.map((a: { publicKey: PublicKey; account: EscrowAccount }) => ({
pda: a.publicKey,
account: a.account as EscrowAccount,
}));
}
async fetchEscrowsForWallet(wallet: PublicKey): Promise<EscrowAccountWithPda[]> {
const asSeller = await (this.program.account as any).escrowAccount.all([
{ memcmp: { offset: 8, bytes: wallet.toBase58() } },
]);
const asBuyer = await (this.program.account as any).escrowAccount.all([
{ memcmp: { offset: 8 + 32, bytes: wallet.toBase58() } },
]);
const seen = new Set<string>();
const results: EscrowAccountWithPda[] = [];
for (const a of [...asSeller, ...asBuyer]) {
const key = a.publicKey.toBase58();
if (!seen.has(key)) {
seen.add(key);
results.push({ pda: a.publicKey, account: a.account as EscrowAccount });
}
}
return results;
}
}

674
sdk/src/idl/descro.json Normal file
View File

@@ -0,0 +1,674 @@
{
"address": "DjVR4EuYV6USMJFfsGZwhZ3y8rtWsmG8EvDY96GTqqi3",
"metadata": {
"name": "descro",
"version": "0.1.0",
"spec": "0.1.0",
"description": "Created with Anchor"
},
"instructions": [
{
"name": "cancel",
"discriminator": [
232,
219,
223,
41,
219,
236,
220,
190
],
"accounts": [
{
"name": "seller",
"writable": true,
"signer": true
},
{
"name": "escrow_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119
]
},
{
"kind": "account",
"path": "escrow_account.seller",
"account": "EscrowAccount"
},
{
"kind": "account",
"path": "escrow_account.escrow_id",
"account": "EscrowAccount"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "complete",
"discriminator": [
0,
77,
224,
147,
136,
25,
88,
76
],
"accounts": [
{
"name": "buyer",
"signer": true
},
{
"name": "seller",
"writable": true
},
{
"name": "escrow_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119
]
},
{
"kind": "account",
"path": "escrow_account.seller",
"account": "EscrowAccount"
},
{
"kind": "account",
"path": "escrow_account.escrow_id",
"account": "EscrowAccount"
}
]
}
},
{
"name": "vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116
]
},
{
"kind": "account",
"path": "escrow_account"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "create_escrow",
"discriminator": [
253,
215,
165,
116,
36,
108,
68,
80
],
"accounts": [
{
"name": "seller",
"writable": true,
"signer": true
},
{
"name": "buyer"
},
{
"name": "escrow_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119
]
},
{
"kind": "account",
"path": "seller"
},
{
"kind": "arg",
"path": "escrow_id"
}
]
}
},
{
"name": "vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116
]
},
{
"kind": "account",
"path": "escrow_account"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "dispute_resolver",
"type": {
"option": "pubkey"
}
},
{
"name": "escrow_id",
"type": "u64"
}
]
},
{
"name": "deposit",
"discriminator": [
242,
35,
198,
137,
82,
225,
242,
182
],
"accounts": [
{
"name": "buyer",
"writable": true,
"signer": true
},
{
"name": "escrow_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119
]
},
{
"kind": "account",
"path": "escrow_account.seller",
"account": "EscrowAccount"
},
{
"kind": "account",
"path": "escrow_account.escrow_id",
"account": "EscrowAccount"
}
]
}
},
{
"name": "vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116
]
},
{
"kind": "account",
"path": "escrow_account"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "dispute",
"discriminator": [
216,
92,
128,
146,
202,
85,
135,
73
],
"accounts": [
{
"name": "initiator",
"signer": true
},
{
"name": "escrow_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119
]
},
{
"kind": "account",
"path": "escrow_account.seller",
"account": "EscrowAccount"
},
{
"kind": "account",
"path": "escrow_account.escrow_id",
"account": "EscrowAccount"
}
]
}
}
],
"args": []
},
{
"name": "resolve",
"discriminator": [
246,
150,
236,
206,
108,
63,
58,
10
],
"accounts": [
{
"name": "resolver",
"signer": true
},
{
"name": "winner",
"writable": true
},
{
"name": "seller",
"writable": true
},
{
"name": "escrow_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119
]
},
{
"kind": "account",
"path": "escrow_account.seller",
"account": "EscrowAccount"
},
{
"kind": "account",
"path": "escrow_account.escrow_id",
"account": "EscrowAccount"
}
]
}
},
{
"name": "vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116
]
},
{
"kind": "account",
"path": "escrow_account"
}
]
}
},
{
"name": "resolver_entry",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
114,
101,
115,
111,
108,
118,
101,
114
]
},
{
"kind": "account",
"path": "escrow_account.dispute_resolver",
"account": "EscrowAccount"
}
],
"program": {
"kind": "const",
"value": [
4,
21,
77,
207,
27,
130,
71,
134,
111,
76,
186,
244,
136,
42,
168,
238,
151,
132,
148,
41,
241,
127,
56,
240,
140,
66,
190,
194,
253,
243,
165,
91
]
}
}
},
{
"name": "escrow_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
}
]
}
},
{
"name": "registry_program"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "winner",
"type": {
"defined": {
"name": "Winner"
}
}
}
]
}
],
"accounts": [
{
"name": "EscrowAccount",
"discriminator": [
36,
69,
48,
18,
128,
225,
125,
135
]
}
],
"errors": [
{
"code": 6000,
"name": "InvalidState",
"msg": "Invalid state for this instruction"
},
{
"code": 6001,
"name": "Unauthorized",
"msg": "Signer is not authorized"
},
{
"code": 6002,
"name": "NoResolverConfigured",
"msg": "No resolver configured for this escrow"
},
{
"code": 6003,
"name": "UnauthorizedResolver",
"msg": "Signer is not the configured resolver"
},
{
"code": 6004,
"name": "Expired",
"msg": "Escrow has expired"
}
],
"types": [
{
"name": "EscrowAccount",
"type": {
"kind": "struct",
"fields": [
{
"name": "seller",
"type": "pubkey"
},
{
"name": "buyer",
"type": "pubkey"
},
{
"name": "amount",
"type": "u64"
},
{
"name": "dispute_resolver",
"type": {
"option": "pubkey"
}
},
{
"name": "state",
"type": {
"defined": {
"name": "EscrowState"
}
}
},
{
"name": "bump",
"type": "u8"
},
{
"name": "vault_bump",
"type": "u8"
},
{
"name": "escrow_id",
"type": "u64"
}
]
}
},
{
"name": "EscrowState",
"type": {
"kind": "enum",
"variants": [
{
"name": "AwaitingDeposit"
},
{
"name": "Active"
},
{
"name": "Disputed"
},
{
"name": "Complete"
},
{
"name": "Cancelled"
}
]
}
},
{
"name": "Winner",
"type": {
"kind": "enum",
"variants": [
{
"name": "Buyer"
},
{
"name": "Seller"
}
]
}
}
]
}

View File

@@ -0,0 +1,385 @@
{
"address": "GwUPAKs3HHzCpj8uhet4NAnxk9GWNwfrYbpihu5DyFp",
"metadata": {
"name": "descro_ext_resolvers",
"version": "0.1.0",
"spec": "0.1.0",
"description": "Resolver Registry for the descro escrow protocol"
},
"instructions": [
{
"name": "register_resolver",
"discriminator": [
76,
101,
253,
229,
153,
242,
212,
230
],
"accounts": [
{
"name": "authority",
"writable": true,
"signer": true
},
{
"name": "resolver_entry",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
114,
101,
115,
111,
108,
118,
101,
114
]
},
{
"kind": "account",
"path": "authority"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "resolver_type",
"type": {
"defined": {
"name": "ResolverType"
}
}
},
{
"name": "name",
"type": "string"
},
{
"name": "description",
"type": "string"
},
{
"name": "fee_bps",
"type": "u16"
},
{
"name": "fee_recipient",
"type": "pubkey"
},
{
"name": "metadata_uri",
"type": "string"
}
]
},
{
"name": "update_resolver",
"discriminator": [
108,
227,
28,
163,
123,
230,
190,
84
],
"accounts": [
{
"name": "authority",
"signer": true
},
{
"name": "resolver_entry",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
114,
101,
115,
111,
108,
118,
101,
114
]
},
{
"kind": "account",
"path": "authority"
}
]
}
}
],
"args": [
{
"name": "name",
"type": "string"
},
{
"name": "description",
"type": "string"
},
{
"name": "fee_bps",
"type": "u16"
},
{
"name": "metadata_uri",
"type": "string"
}
]
},
{
"name": "update_stats",
"discriminator": [
145,
138,
9,
150,
178,
31,
158,
244
],
"accounts": [
{
"name": "escrow_authority",
"docs": [
"Must be the Escrow Program's authority PDA — only it can sign this."
],
"signer": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
101,
115,
99,
114,
111,
119,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
}
],
"program": {
"kind": "const",
"value": [
189,
46,
196,
9,
38,
68,
13,
236,
154,
101,
74,
161,
29,
155,
110,
167,
230,
204,
79,
86,
74,
46,
229,
168,
214,
228,
65,
126,
160,
53,
53,
204
]
}
}
},
{
"name": "resolver_entry",
"writable": true
}
],
"args": [
{
"name": "ruling",
"type": {
"defined": {
"name": "Ruling"
}
}
}
]
}
],
"accounts": [
{
"name": "ResolverEntry",
"discriminator": [
0,
60,
55,
58,
157,
135,
51,
191
]
}
],
"errors": [
{
"code": 6000,
"name": "Unauthorized",
"msg": "Signer is not the registered authority"
},
{
"code": 6001,
"name": "UnauthorizedCaller",
"msg": "Caller is not the authorized escrow program"
},
{
"code": 6002,
"name": "InvalidFeeBps",
"msg": "Fee basis points must be <= 10000"
},
{
"code": 6003,
"name": "EmptyName",
"msg": "Name must not be empty"
}
],
"types": [
{
"name": "ResolverEntry",
"type": {
"kind": "struct",
"fields": [
{
"name": "authority",
"type": "pubkey"
},
{
"name": "resolver_type",
"type": {
"defined": {
"name": "ResolverType"
}
}
},
{
"name": "name",
"type": "string"
},
{
"name": "description",
"type": "string"
},
{
"name": "fee_bps",
"type": "u16"
},
{
"name": "fee_recipient",
"type": "pubkey"
},
{
"name": "metadata_uri",
"type": "string"
},
{
"name": "total_resolved",
"type": "u64"
},
{
"name": "ruled_for_buyer",
"type": "u64"
},
{
"name": "ruled_for_seller",
"type": "u64"
},
{
"name": "registered_at",
"type": "i64"
}
]
}
},
{
"name": "ResolverType",
"type": {
"kind": "enum",
"variants": [
{
"name": "CentralAuthority"
},
{
"name": "JuryDAO"
},
{
"name": "MAD"
},
{
"name": "Algorithmic"
},
{
"name": "Multisig"
}
]
}
},
{
"name": "Ruling",
"docs": [
"Passed to update_stats; mirrors the Escrow program's Winner enum."
],
"type": {
"kind": "enum",
"variants": [
{
"name": "Buyer"
},
{
"name": "Seller"
}
]
}
}
]
}

19
sdk/src/index.ts Normal file
View File

@@ -0,0 +1,19 @@
export * from "./types";
export * from "./pda";
export * from "./escrow";
export * from "./registry";
export * from "./listener";
import { AnchorProvider } from "@coral-xyz/anchor";
import { EscrowClient } from "./escrow";
import { RegistryClient } from "./registry";
export class DescroSdk {
readonly escrow: EscrowClient;
readonly registry: RegistryClient;
constructor(provider: AnchorProvider) {
this.escrow = new EscrowClient(provider);
this.registry = new RegistryClient(provider);
}
}

53
sdk/src/listener.ts Normal file
View File

@@ -0,0 +1,53 @@
import { Connection, PublicKey, AccountInfo } from "@solana/web3.js";
import { AnchorProvider, Program } from "@coral-xyz/anchor";
import type { Idl } from "@coral-xyz/anchor";
import descroIdl from "./idl/descro.json";
import { ESCROW_PROGRAM_ID } from "./pda";
import type { EscrowAccount } from "./types";
function decodeEscrowAccount(
program: Program,
info: AccountInfo<Buffer>
): EscrowAccount | null {
try {
return (program.coder.accounts as any).decode("EscrowAccount", info.data) as EscrowAccount;
} catch {
return null;
}
}
export function subscribeEscrow(
connection: Connection,
pda: PublicKey,
cb: (account: EscrowAccount | null) => void
): () => void {
const provider = new AnchorProvider(connection, {} as never, {});
const program = new Program(descroIdl as Idl, new PublicKey(ESCROW_PROGRAM_ID), provider);
const subId = connection.onAccountChange(pda, (info) => {
cb(decodeEscrowAccount(program, info as AccountInfo<Buffer>));
});
return () => {
connection.removeAccountChangeListener(subId).catch(() => undefined);
};
}
export function subscribeAll(
connection: Connection,
programId: PublicKey = ESCROW_PROGRAM_ID,
cb: (pda: PublicKey, account: EscrowAccount | null) => void
): () => void {
const provider = new AnchorProvider(connection, {} as never, {});
const program = new Program(descroIdl as Idl, new PublicKey(programId), provider);
const subId = connection.onProgramAccountChange(programId, (keyedAccountInfo) => {
const pda = keyedAccountInfo.accountId;
const info = keyedAccountInfo.accountInfo;
cb(pda, decodeEscrowAccount(program, info as AccountInfo<Buffer>));
});
return () => {
connection.removeProgramAccountChangeListener(subId).catch(() => undefined);
};
}

52
sdk/src/pda.ts Normal file
View File

@@ -0,0 +1,52 @@
import { PublicKey } from "@solana/web3.js";
import BN from "bn.js";
export const ESCROW_PROGRAM_ID = new PublicKey(
"DjVR4EuYV6USMJFfsGZwhZ3y8rtWsmG8EvDY96GTqqi3"
);
export const REGISTRY_PROGRAM_ID = new PublicKey(
"GwUPAKs3HHzCpj8uhet4NAnxk9GWNwfrYbpihu5DyFp"
);
export function deriveEscrowPda(
seller: PublicKey,
escrowId: BN | bigint | number,
programId: PublicKey = ESCROW_PROGRAM_ID
): [PublicKey, number] {
const id = new BN(escrowId.toString());
const idBuf = Buffer.alloc(8);
idBuf.writeBigUInt64LE(BigInt(id.toString()));
return PublicKey.findProgramAddressSync(
[Buffer.from("escrow"), seller.toBuffer(), idBuf],
programId
);
}
export function deriveVaultPda(
escrowPda: PublicKey,
programId: PublicKey = ESCROW_PROGRAM_ID
): [PublicKey, number] {
return PublicKey.findProgramAddressSync(
[Buffer.from("vault"), escrowPda.toBuffer()],
programId
);
}
export function deriveEscrowAuthorityPda(
programId: PublicKey = ESCROW_PROGRAM_ID
): [PublicKey, number] {
return PublicKey.findProgramAddressSync(
[Buffer.from("escrow_authority")],
programId
);
}
export function deriveResolverEntryPda(
authority: PublicKey,
registryProgramId: PublicKey = REGISTRY_PROGRAM_ID
): [PublicKey, number] {
return PublicKey.findProgramAddressSync(
[Buffer.from("resolver"), authority.toBuffer()],
registryProgramId
);
}

88
sdk/src/registry.ts Normal file
View File

@@ -0,0 +1,88 @@
import { PublicKey, TransactionInstruction, SystemProgram } from "@solana/web3.js";
import { AnchorProvider, Program } from "@coral-xyz/anchor";
import type { Idl } from "@coral-xyz/anchor";
import registryIdl from "./idl/descro_ext_resolvers.json";
import { REGISTRY_PROGRAM_ID, deriveResolverEntryPda } from "./pda";
import type { ResolverEntry, ResolverEntryWithPda, ResolverType } from "./types";
export class RegistryClient {
readonly program: Program;
readonly provider: AnchorProvider;
constructor(provider: AnchorProvider) {
this.provider = provider;
this.program = new Program(
registryIdl as Idl,
new PublicKey(REGISTRY_PROGRAM_ID),
provider
);
}
async buildRegisterResolver(params: {
authority: PublicKey;
resolverType: ResolverType;
name: string;
description: string;
feeBps: number;
feeRecipient: PublicKey;
metadataUri: string;
}): Promise<TransactionInstruction> {
const { authority, resolverType, name, description, feeBps, feeRecipient, metadataUri } = params;
const [resolverEntry] = deriveResolverEntryPda(authority);
return await (this.program.methods as any)
.registerResolver(resolverType, name, description, feeBps, feeRecipient, metadataUri)
.accounts({
authority,
resolverEntry,
systemProgram: SystemProgram.programId,
})
.instruction();
}
async buildUpdateResolver(params: {
authority: PublicKey;
name: string;
description: string;
feeBps: number;
metadataUri: string;
}): Promise<TransactionInstruction> {
const { authority, name, description, feeBps, metadataUri } = params;
const [resolverEntry] = deriveResolverEntryPda(authority);
return await (this.program.methods as any)
.updateResolver(name, description, feeBps, metadataUri)
.accounts({
authority,
resolverEntry,
})
.instruction();
}
async fetchResolver(authority: PublicKey): Promise<ResolverEntry | null> {
try {
const [pda] = deriveResolverEntryPda(authority);
const raw = await (this.program.account as any).resolverEntry.fetch(pda);
return raw as ResolverEntry;
} catch {
return null;
}
}
async fetchResolverByPda(pda: PublicKey): Promise<ResolverEntry | null> {
try {
const raw = await (this.program.account as any).resolverEntry.fetch(pda);
return raw as ResolverEntry;
} catch {
return null;
}
}
async fetchAllResolvers(): Promise<ResolverEntryWithPda[]> {
const accounts = await (this.program.account as any).resolverEntry.all();
return accounts.map((a: { publicKey: PublicKey; account: ResolverEntry }) => ({
pda: a.publicKey,
account: a.account as ResolverEntry,
}));
}
}

87
sdk/src/types.ts Normal file
View File

@@ -0,0 +1,87 @@
import { PublicKey } from "@solana/web3.js";
import BN from "bn.js";
export type EscrowState =
| { awaitingDeposit: Record<string, never> }
| { active: Record<string, never> }
| { disputed: Record<string, never> }
| { complete: Record<string, never> }
| { cancelled: Record<string, never> };
export type Winner = { buyer: Record<string, never> } | { seller: Record<string, never> };
export type ResolverType =
| { centralAuthority: Record<string, never> }
| { juryDAO: Record<string, never> }
| { mad: Record<string, never> }
| { algorithmic: Record<string, never> }
| { multisig: Record<string, never> };
export interface EscrowAccount {
seller: PublicKey;
buyer: PublicKey;
amount: BN;
disputeResolver: PublicKey | null;
state: EscrowState;
bump: number;
vaultBump: number;
escrowId: BN;
}
export interface ResolverEntry {
authority: PublicKey;
resolverType: ResolverType;
name: string;
description: string;
feeBps: number;
feeRecipient: PublicKey;
metadataUri: string;
totalResolved: BN;
ruledForBuyer: BN;
ruledForSeller: BN;
registeredAt: BN;
}
export interface EscrowAccountWithPda {
pda: PublicKey;
account: EscrowAccount;
}
export interface ResolverEntryWithPda {
pda: PublicKey;
account: ResolverEntry;
}
export function isAwaitingDeposit(state: EscrowState): boolean {
return "awaitingDeposit" in state;
}
export function isActive(state: EscrowState): boolean {
return "active" in state;
}
export function isDisputed(state: EscrowState): boolean {
return "disputed" in state;
}
export function isComplete(state: EscrowState): boolean {
return "complete" in state;
}
export function isCancelled(state: EscrowState): boolean {
return "cancelled" in state;
}
export function escrowStateLabel(state: EscrowState): string {
if (isAwaitingDeposit(state)) return "AwaitingDeposit";
if (isActive(state)) return "Active";
if (isDisputed(state)) return "Disputed";
if (isComplete(state)) return "Complete";
if (isCancelled(state)) return "Cancelled";
return "Unknown";
}
export function resolverTypeLabel(rt: ResolverType): string {
if ("centralAuthority" in rt) return "CentralAuthority";
if ("juryDAO" in rt) return "JuryDAO";
if ("mad" in rt) return "MAD";
if ("algorithmic" in rt) return "Algorithmic";
if ("multisig" in rt) return "Multisig";
return "Unknown";
}

16
sdk/tsconfig.json Normal file
View File

@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "esnext",
"moduleResolution": "bundler",
"lib": ["ES2020"],
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"declaration": true,
"declarationMap": true,
"outDir": "./dist"
},
"include": ["src/**/*"]
}