@leashmarket/core 0.1.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 +32 -0
- package/dist/agent/agent.d.ts +8 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +14 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/treasury-pda.d.ts +49 -0
- package/dist/agent/treasury-pda.d.ts.map +1 -0
- package/dist/agent/treasury-pda.js +55 -0
- package/dist/agent/treasury-pda.js.map +1 -0
- package/dist/explorer/index.d.ts +55 -0
- package/dist/explorer/index.d.ts.map +1 -0
- package/dist/explorer/index.js +95 -0
- package/dist/explorer/index.js.map +1 -0
- package/dist/fees/leash-fee.d.ts +248 -0
- package/dist/fees/leash-fee.d.ts.map +1 -0
- package/dist/fees/leash-fee.js +246 -0
- package/dist/fees/leash-fee.js.map +1 -0
- package/dist/format/index.d.ts +55 -0
- package/dist/format/index.d.ts.map +1 -0
- package/dist/format/index.js +130 -0
- package/dist/format/index.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/evaluate.d.ts +17 -0
- package/dist/policy/evaluate.d.ts.map +1 -0
- package/dist/policy/evaluate.js +46 -0
- package/dist/policy/evaluate.js.map +1 -0
- package/dist/policy/state.d.ts +8 -0
- package/dist/policy/state.d.ts.map +1 -0
- package/dist/policy/state.js +2 -0
- package/dist/policy/state.js.map +1 -0
- package/dist/receipt/build.d.ts +5 -0
- package/dist/receipt/build.d.ts.map +1 -0
- package/dist/receipt/build.js +9 -0
- package/dist/receipt/build.js.map +1 -0
- package/dist/receipt/hash.d.ts +15 -0
- package/dist/receipt/hash.d.ts.map +1 -0
- package/dist/receipt/hash.js +40 -0
- package/dist/receipt/hash.js.map +1 -0
- package/dist/receipt/verify.d.ts +10 -0
- package/dist/receipt/verify.d.ts.map +1 -0
- package/dist/receipt/verify.js +36 -0
- package/dist/receipt/verify.js.map +1 -0
- package/dist/tokens/index.d.ts +86 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +163 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/treasury/balance.d.ts +3 -0
- package/dist/treasury/balance.d.ts.map +1 -0
- package/dist/treasury/balance.js +13 -0
- package/dist/treasury/balance.js.map +1 -0
- package/dist/treasury/inspect-token-account.d.ts +46 -0
- package/dist/treasury/inspect-token-account.d.ts.map +1 -0
- package/dist/treasury/inspect-token-account.js +67 -0
- package/dist/treasury/inspect-token-account.js.map +1 -0
- package/dist/treasury/list-balances.d.ts +57 -0
- package/dist/treasury/list-balances.d.ts.map +1 -0
- package/dist/treasury/list-balances.js +115 -0
- package/dist/treasury/list-balances.js.map +1 -0
- package/dist/treasury/pause.d.ts +32 -0
- package/dist/treasury/pause.d.ts.map +1 -0
- package/dist/treasury/pause.js +40 -0
- package/dist/treasury/pause.js.map +1 -0
- package/dist/treasury/withdraw.d.ts +13 -0
- package/dist/treasury/withdraw.d.ts.map +1 -0
- package/dist/treasury/withdraw.js +4 -0
- package/dist/treasury/withdraw.js.map +1 -0
- package/dist/wallet/index.d.ts +3 -0
- package/dist/wallet/index.d.ts.map +1 -0
- package/dist/wallet/index.js +2 -0
- package/dist/wallet/index.js.map +1 -0
- package/dist/x402/client.d.ts +72 -0
- package/dist/x402/client.d.ts.map +1 -0
- package/dist/x402/client.js +94 -0
- package/dist/x402/client.js.map +1 -0
- package/dist/x402/delegate-scheme.d.ts +107 -0
- package/dist/x402/delegate-scheme.d.ts.map +1 -0
- package/dist/x402/delegate-scheme.js +268 -0
- package/dist/x402/delegate-scheme.js.map +1 -0
- package/dist/x402/discovery.d.ts +110 -0
- package/dist/x402/discovery.d.ts.map +1 -0
- package/dist/x402/discovery.js +213 -0
- package/dist/x402/discovery.js.map +1 -0
- package/dist/x402/envelope.d.ts +65 -0
- package/dist/x402/envelope.d.ts.map +1 -0
- package/dist/x402/envelope.js +67 -0
- package/dist/x402/envelope.js.map +1 -0
- package/dist/x402/facilitator.d.ts +45 -0
- package/dist/x402/facilitator.d.ts.map +1 -0
- package/dist/x402/facilitator.js +61 -0
- package/dist/x402/facilitator.js.map +1 -0
- package/dist/x402/headers.d.ts +51 -0
- package/dist/x402/headers.d.ts.map +1 -0
- package/dist/x402/headers.js +84 -0
- package/dist/x402/headers.js.map +1 -0
- package/dist/x402/parse.d.ts +20 -0
- package/dist/x402/parse.d.ts.map +1 -0
- package/dist/x402/parse.js +31 -0
- package/dist/x402/parse.js.map +1 -0
- package/dist/x402/webhook.d.ts +48 -0
- package/dist/x402/webhook.d.ts.map +1 -0
- package/dist/x402/webhook.js +88 -0
- package/dist/x402/webhook.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous SHA-256 via `@noble/hashes` so receipts can be hashed in
|
|
3
|
+
* Node, in the browser (Privy buyer), and in workers without depending
|
|
4
|
+
* on `node:crypto` or async `crypto.subtle`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function requestHash(input: {
|
|
7
|
+
method: string;
|
|
8
|
+
url: string;
|
|
9
|
+
body: string | null;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function sha256Hex(data: string): string;
|
|
13
|
+
/** Stable JSON stringify with sorted keys (shallow + deep for plain objects). */
|
|
14
|
+
export declare function canonicalJson(value: unknown): string;
|
|
15
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/receipt/hash.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,GAAG,MAAM,CAUT;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
2
|
+
import { bytesToHex, utf8ToBytes } from '@noble/hashes/utils';
|
|
3
|
+
/**
|
|
4
|
+
* Synchronous SHA-256 via `@noble/hashes` so receipts can be hashed in
|
|
5
|
+
* Node, in the browser (Privy buyer), and in workers without depending
|
|
6
|
+
* on `node:crypto` or async `crypto.subtle`.
|
|
7
|
+
*/
|
|
8
|
+
export function requestHash(input) {
|
|
9
|
+
const parts = [input.method, input.url, input.body ?? ''];
|
|
10
|
+
if (input.headers) {
|
|
11
|
+
const keys = Object.keys(input.headers).sort();
|
|
12
|
+
for (const k of keys) {
|
|
13
|
+
parts.push(`${k}=${String(input.headers[k])}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const concatenated = `${parts.join('\n')}\n`;
|
|
17
|
+
return `sha256:${bytesToHex(sha256(utf8ToBytes(concatenated)))}`;
|
|
18
|
+
}
|
|
19
|
+
export function sha256Hex(data) {
|
|
20
|
+
return bytesToHex(sha256(utf8ToBytes(data)));
|
|
21
|
+
}
|
|
22
|
+
/** Stable JSON stringify with sorted keys (shallow + deep for plain objects). */
|
|
23
|
+
export function canonicalJson(value) {
|
|
24
|
+
return JSON.stringify(sortKeys(value));
|
|
25
|
+
}
|
|
26
|
+
function sortKeys(value) {
|
|
27
|
+
if (value === null || typeof value !== 'object') {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
return value.map(sortKeys);
|
|
32
|
+
}
|
|
33
|
+
const obj = value;
|
|
34
|
+
const out = {};
|
|
35
|
+
for (const k of Object.keys(obj).sort()) {
|
|
36
|
+
out[k] = sortKeys(obj[k]);
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/receipt/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAK3B;IACC,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACpE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7C,OAAO,UAAU,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACxC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/receipt/verify.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CA8BhE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ReceiptV1Schema } from '@leashmarket/schemas';
|
|
2
|
+
import { computeReceiptHash } from './build.js';
|
|
3
|
+
export function verifyReceiptChain(lines) {
|
|
4
|
+
let prev = null;
|
|
5
|
+
for (let i = 0; i < lines.length; i++) {
|
|
6
|
+
const line = lines[i]?.trim();
|
|
7
|
+
if (!line)
|
|
8
|
+
continue;
|
|
9
|
+
let parsed;
|
|
10
|
+
try {
|
|
11
|
+
parsed = JSON.parse(line);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return { ok: false, nonce: i, reason: 'invalid_json' };
|
|
15
|
+
}
|
|
16
|
+
const r = ReceiptV1Schema.safeParse(parsed);
|
|
17
|
+
if (!r.success) {
|
|
18
|
+
return { ok: false, nonce: i, reason: 'invalid_schema' };
|
|
19
|
+
}
|
|
20
|
+
const rec = r.data;
|
|
21
|
+
if (rec.nonce !== i) {
|
|
22
|
+
return { ok: false, nonce: i, reason: 'nonce_mismatch' };
|
|
23
|
+
}
|
|
24
|
+
if (rec.prev_receipt_hash !== prev) {
|
|
25
|
+
return { ok: false, nonce: i, reason: 'prev_hash_mismatch' };
|
|
26
|
+
}
|
|
27
|
+
const { receipt_hash, ...rest } = rec;
|
|
28
|
+
const expected = computeReceiptHash(rest);
|
|
29
|
+
if (receipt_hash !== expected) {
|
|
30
|
+
return { ok: false, nonce: i, reason: 'receipt_hash_mismatch' };
|
|
31
|
+
}
|
|
32
|
+
prev = rec.receipt_hash;
|
|
33
|
+
}
|
|
34
|
+
return { ok: true, count: lines.filter((l) => l.trim()).length };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/receipt/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMhD,MAAM,UAAU,kBAAkB,CAAC,KAAe;IAChD,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACzD,CAAC;QACD,MAAM,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC3D,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,GAAG,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;QAC/D,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC;QACtC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QAClE,CAAC;QACD,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static registry of well-known SPL token mints used by the Leash UI / CLI
|
|
3
|
+
* surfaces to enrich raw RPC balances with symbols, decimals, and the
|
|
4
|
+
* correct token program id. The registry deliberately stays small —
|
|
5
|
+
* stables + bluechips that are policy-relevant for x402 / agent treasuries.
|
|
6
|
+
*
|
|
7
|
+
* For full registry resolution (Token-2022 metadata, Jupiter token list,
|
|
8
|
+
* etc.) consume an external source; this module covers the common case so
|
|
9
|
+
* SDK consumers never need to hard-code mint addresses.
|
|
10
|
+
*
|
|
11
|
+
* Mainnet and devnet entries are listed separately because devnet stables
|
|
12
|
+
* are usually faucet-mintable test versions with different mint authorities
|
|
13
|
+
* than their mainnet counterparts.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
16
|
+
export declare const TOKEN_2022_PROGRAM_ID = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
17
|
+
export type TokenProgram = 'spl-token' | 'spl-token-2022';
|
|
18
|
+
export type TokenNetwork = 'mainnet' | 'devnet';
|
|
19
|
+
export type KnownToken = {
|
|
20
|
+
mint: string;
|
|
21
|
+
symbol: string;
|
|
22
|
+
name: string;
|
|
23
|
+
decimals: number;
|
|
24
|
+
/**
|
|
25
|
+
* SPL token program owning this mint. Defaults to legacy `spl-token` when
|
|
26
|
+
* omitted by callers; explicit on every entry below for clarity.
|
|
27
|
+
*/
|
|
28
|
+
program: TokenProgram;
|
|
29
|
+
/** True when the token is a USD-pegged stablecoin. */
|
|
30
|
+
stable: boolean;
|
|
31
|
+
};
|
|
32
|
+
export declare const KNOWN_TOKENS: Record<TokenNetwork, ReadonlyArray<KnownToken>>;
|
|
33
|
+
/** Look up a known token by mint address on a given network. */
|
|
34
|
+
export declare function lookupToken(mint: string, network: TokenNetwork): KnownToken | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Symbols of the well-known USD-pegged stablecoins Leash supports for x402
|
|
37
|
+
* settlement. Restricted to the registry's stable entries so consumers can
|
|
38
|
+
* pin a typed dropdown without re-deriving the list.
|
|
39
|
+
*/
|
|
40
|
+
export type KnownStableSymbol = 'USDC' | 'USDT' | 'USDG';
|
|
41
|
+
/** All stablecoin tickers we recognise on at least one network. */
|
|
42
|
+
export declare const KNOWN_STABLE_SYMBOLS: ReadonlyArray<KnownStableSymbol>;
|
|
43
|
+
/**
|
|
44
|
+
* Look up a known token by ticker symbol (case-insensitive) on a given
|
|
45
|
+
* network. Useful for translating a user-facing currency dropdown into the
|
|
46
|
+
* underlying mint address required by x402 `AssetAmount` prices.
|
|
47
|
+
*/
|
|
48
|
+
export declare function lookupTokenBySymbol(symbol: string, network: TokenNetwork): KnownToken | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Reverse-lookup a currency ticker for an asset mint. Falls back to `'USDC'`
|
|
51
|
+
* (the v0.1 default settlement currency) when the mint is unknown — buyer
|
|
52
|
+
* receipts surface a usable label even if the seller advertises a token the
|
|
53
|
+
* Leash registry hasn't catalogued yet.
|
|
54
|
+
*/
|
|
55
|
+
export declare function currencyForAsset(asset: string | null | undefined, network: TokenNetwork): string;
|
|
56
|
+
/**
|
|
57
|
+
* Mints we always want to render in a treasury UI even when the agent
|
|
58
|
+
* holds zero — the headline stables. Other tokens only appear once the
|
|
59
|
+
* agent actually holds a balance.
|
|
60
|
+
*/
|
|
61
|
+
export declare function pinnedMints(network: TokenNetwork): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Heuristic mapping of an RPC URL to a logical network bucket. Treats
|
|
64
|
+
* anything containing `devnet`, `localhost`, or a private-network IP as
|
|
65
|
+
* devnet; everything else as mainnet.
|
|
66
|
+
*/
|
|
67
|
+
export declare function networkFromRpc(rpc: string): TokenNetwork;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the canonical USDC mint for the given network. Used by buyer-kit
|
|
70
|
+
* pre-flight checks ("does the treasury have enough?") and by UI to seed
|
|
71
|
+
* default token selectors.
|
|
72
|
+
*/
|
|
73
|
+
export declare function defaultUsdcMint(network: TokenNetwork): KnownToken;
|
|
74
|
+
/**
|
|
75
|
+
* Look up the SPL token program a known mint lives under (`spl-token` for
|
|
76
|
+
* legacy or `spl-token-2022` for Token-2022). Tries both networks since
|
|
77
|
+
* known stable mints are disjoint, so callers don't have to thread the
|
|
78
|
+
* x402 envelope's CAIP-2 network down through every layer.
|
|
79
|
+
*
|
|
80
|
+
* Returns `null` when the mint isn't catalogued — callers should default
|
|
81
|
+
* to legacy SPL token for back-compat, but this lets surfaces that DO
|
|
82
|
+
* understand Token-2022 (Pay card, buyer-kit preflight, withdraw flow)
|
|
83
|
+
* pick the right ATA without hard-coding mints.
|
|
84
|
+
*/
|
|
85
|
+
export declare function tokenProgramForMint(mint: string): TokenProgram | null;
|
|
86
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,gBAAgB,gDAAgD,CAAC;AAC9E,eAAO,MAAM,qBAAqB,gDAAgD,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,YAAY,CAAC;IACtB,sDAAsD;IACtD,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAwEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,UAAU,CAAC,CAGxE,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,UAAU,GAAG,SAAS,CAEvF;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,iBAAiB,CAA4B,CAAC;AAE/F;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,UAAU,GAAG,SAAS,CAGjG;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,MAAM,CAGhG;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAExD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CAMjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAOrE"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static registry of well-known SPL token mints used by the Leash UI / CLI
|
|
3
|
+
* surfaces to enrich raw RPC balances with symbols, decimals, and the
|
|
4
|
+
* correct token program id. The registry deliberately stays small —
|
|
5
|
+
* stables + bluechips that are policy-relevant for x402 / agent treasuries.
|
|
6
|
+
*
|
|
7
|
+
* For full registry resolution (Token-2022 metadata, Jupiter token list,
|
|
8
|
+
* etc.) consume an external source; this module covers the common case so
|
|
9
|
+
* SDK consumers never need to hard-code mint addresses.
|
|
10
|
+
*
|
|
11
|
+
* Mainnet and devnet entries are listed separately because devnet stables
|
|
12
|
+
* are usually faucet-mintable test versions with different mint authorities
|
|
13
|
+
* than their mainnet counterparts.
|
|
14
|
+
*/
|
|
15
|
+
export const TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';
|
|
16
|
+
export const TOKEN_2022_PROGRAM_ID = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb';
|
|
17
|
+
const MAINNET = [
|
|
18
|
+
{
|
|
19
|
+
mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
20
|
+
symbol: 'USDC',
|
|
21
|
+
name: 'USD Coin',
|
|
22
|
+
decimals: 6,
|
|
23
|
+
program: 'spl-token',
|
|
24
|
+
stable: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
mint: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
|
28
|
+
symbol: 'USDT',
|
|
29
|
+
name: 'Tether USD',
|
|
30
|
+
decimals: 6,
|
|
31
|
+
program: 'spl-token',
|
|
32
|
+
stable: true,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
mint: '2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH',
|
|
36
|
+
symbol: 'USDG',
|
|
37
|
+
name: 'Global Dollar',
|
|
38
|
+
decimals: 6,
|
|
39
|
+
program: 'spl-token-2022',
|
|
40
|
+
stable: true,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
mint: 'So11111111111111111111111111111111111111112',
|
|
44
|
+
symbol: 'wSOL',
|
|
45
|
+
name: 'Wrapped SOL',
|
|
46
|
+
decimals: 9,
|
|
47
|
+
program: 'spl-token',
|
|
48
|
+
stable: false,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
const DEVNET = [
|
|
52
|
+
{
|
|
53
|
+
mint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',
|
|
54
|
+
symbol: 'USDC',
|
|
55
|
+
name: 'USD Coin (devnet)',
|
|
56
|
+
decimals: 6,
|
|
57
|
+
program: 'spl-token',
|
|
58
|
+
stable: true,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
mint: 'EcFc2cMyZxaKBkFK1XooxiyDyCPneLXiMwSJiVY6eTad',
|
|
62
|
+
symbol: 'USDT',
|
|
63
|
+
name: 'Tether USD (devnet)',
|
|
64
|
+
decimals: 6,
|
|
65
|
+
program: 'spl-token',
|
|
66
|
+
stable: true,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
mint: '4F6PM96JJxngmHnZLBh9n58RH4aTVNWvDs2nuwrT5BP7',
|
|
70
|
+
symbol: 'USDG',
|
|
71
|
+
name: 'Global Dollar (devnet)',
|
|
72
|
+
decimals: 6,
|
|
73
|
+
program: 'spl-token-2022',
|
|
74
|
+
stable: true,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
mint: 'So11111111111111111111111111111111111111112',
|
|
78
|
+
symbol: 'wSOL',
|
|
79
|
+
name: 'Wrapped SOL (devnet)',
|
|
80
|
+
decimals: 9,
|
|
81
|
+
program: 'spl-token',
|
|
82
|
+
stable: false,
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
export const KNOWN_TOKENS = {
|
|
86
|
+
mainnet: MAINNET,
|
|
87
|
+
devnet: DEVNET,
|
|
88
|
+
};
|
|
89
|
+
/** Look up a known token by mint address on a given network. */
|
|
90
|
+
export function lookupToken(mint, network) {
|
|
91
|
+
return KNOWN_TOKENS[network].find((t) => t.mint === mint);
|
|
92
|
+
}
|
|
93
|
+
/** All stablecoin tickers we recognise on at least one network. */
|
|
94
|
+
export const KNOWN_STABLE_SYMBOLS = ['USDC', 'USDT', 'USDG'];
|
|
95
|
+
/**
|
|
96
|
+
* Look up a known token by ticker symbol (case-insensitive) on a given
|
|
97
|
+
* network. Useful for translating a user-facing currency dropdown into the
|
|
98
|
+
* underlying mint address required by x402 `AssetAmount` prices.
|
|
99
|
+
*/
|
|
100
|
+
export function lookupTokenBySymbol(symbol, network) {
|
|
101
|
+
const upper = symbol.trim().toUpperCase();
|
|
102
|
+
return KNOWN_TOKENS[network].find((t) => t.symbol.toUpperCase() === upper);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Reverse-lookup a currency ticker for an asset mint. Falls back to `'USDC'`
|
|
106
|
+
* (the v0.1 default settlement currency) when the mint is unknown — buyer
|
|
107
|
+
* receipts surface a usable label even if the seller advertises a token the
|
|
108
|
+
* Leash registry hasn't catalogued yet.
|
|
109
|
+
*/
|
|
110
|
+
export function currencyForAsset(asset, network) {
|
|
111
|
+
if (!asset)
|
|
112
|
+
return 'USDC';
|
|
113
|
+
return lookupToken(asset, network)?.symbol ?? 'USDC';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Mints we always want to render in a treasury UI even when the agent
|
|
117
|
+
* holds zero — the headline stables. Other tokens only appear once the
|
|
118
|
+
* agent actually holds a balance.
|
|
119
|
+
*/
|
|
120
|
+
export function pinnedMints(network) {
|
|
121
|
+
return KNOWN_TOKENS[network].filter((t) => t.stable).map((t) => t.mint);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Heuristic mapping of an RPC URL to a logical network bucket. Treats
|
|
125
|
+
* anything containing `devnet`, `localhost`, or a private-network IP as
|
|
126
|
+
* devnet; everything else as mainnet.
|
|
127
|
+
*/
|
|
128
|
+
export function networkFromRpc(rpc) {
|
|
129
|
+
return /devnet|localhost|127\.0\.0\.1/.test(rpc) ? 'devnet' : 'mainnet';
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Resolve the canonical USDC mint for the given network. Used by buyer-kit
|
|
133
|
+
* pre-flight checks ("does the treasury have enough?") and by UI to seed
|
|
134
|
+
* default token selectors.
|
|
135
|
+
*/
|
|
136
|
+
export function defaultUsdcMint(network) {
|
|
137
|
+
const usdc = KNOWN_TOKENS[network].find((t) => t.symbol === 'USDC');
|
|
138
|
+
if (!usdc) {
|
|
139
|
+
throw new Error(`No USDC mint registered for network "${network}"`);
|
|
140
|
+
}
|
|
141
|
+
return usdc;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Look up the SPL token program a known mint lives under (`spl-token` for
|
|
145
|
+
* legacy or `spl-token-2022` for Token-2022). Tries both networks since
|
|
146
|
+
* known stable mints are disjoint, so callers don't have to thread the
|
|
147
|
+
* x402 envelope's CAIP-2 network down through every layer.
|
|
148
|
+
*
|
|
149
|
+
* Returns `null` when the mint isn't catalogued — callers should default
|
|
150
|
+
* to legacy SPL token for back-compat, but this lets surfaces that DO
|
|
151
|
+
* understand Token-2022 (Pay card, buyer-kit preflight, withdraw flow)
|
|
152
|
+
* pick the right ATA without hard-coding mints.
|
|
153
|
+
*/
|
|
154
|
+
export function tokenProgramForMint(mint) {
|
|
155
|
+
const trimmed = mint.trim();
|
|
156
|
+
for (const net of ['mainnet', 'devnet']) {
|
|
157
|
+
const hit = KNOWN_TOKENS[net].find((t) => t.mint === trimmed);
|
|
158
|
+
if (hit)
|
|
159
|
+
return hit.program;
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,6CAA6C,CAAC;AAC9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,6CAA6C,CAAC;AAmBnF,MAAM,OAAO,GAA8B;IACzC;QACE,IAAI,EAAE,8CAA8C;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,IAAI;KACb;IACD;QACE,IAAI,EAAE,8CAA8C;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,IAAI;KACb;IACD;QACE,IAAI,EAAE,8CAA8C;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,eAAe;QACrB,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,gBAAgB;QACzB,MAAM,EAAE,IAAI;KACb;IACD;QACE,IAAI,EAAE,6CAA6C;QACnD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,aAAa;QACnB,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,KAAK;KACd;CACF,CAAC;AAEF,MAAM,MAAM,GAA8B;IACxC;QACE,IAAI,EAAE,8CAA8C;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,mBAAmB;QACzB,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,IAAI;KACb;IACD;QACE,IAAI,EAAE,8CAA8C;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,qBAAqB;QAC3B,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,IAAI;KACb;IACD;QACE,IAAI,EAAE,8CAA8C;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,wBAAwB;QAC9B,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,gBAAgB;QACzB,MAAM,EAAE,IAAI;KACb;IACD;QACE,IAAI,EAAE,6CAA6C;QACnD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,sBAAsB;QAC5B,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,KAAK;KACd;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAoD;IAC3E,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,MAAM;CACf,CAAC;AAEF,gEAAgE;AAChE,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAqB;IAC7D,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC5D,CAAC;AASD,mEAAmE;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAqC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/F;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,OAAqB;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAgC,EAAE,OAAqB;IACtF,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1B,OAAO,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,MAAM,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAqB;IAC/C,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAqB;IACnD,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACpE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,wCAAwC,OAAO,GAAG,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAU,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC9D,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/treasury/balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAUjB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
export async function getSplTokenBalance(connection, ownerBase58, mintBase58) {
|
|
3
|
+
const owner = new PublicKey(ownerBase58);
|
|
4
|
+
const mint = new PublicKey(mintBase58);
|
|
5
|
+
const accounts = await connection.getParsedTokenAccountsByOwner(owner, { mint });
|
|
6
|
+
let sum = 0n;
|
|
7
|
+
for (const { account } of accounts.value) {
|
|
8
|
+
const amount = account.data.parsed.info.tokenAmount.amount;
|
|
9
|
+
sum += BigInt(amount);
|
|
10
|
+
}
|
|
11
|
+
return sum;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/treasury/balance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAsB,EACtB,WAAmB,EACnB,UAAkB;IAElB,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,6BAA6B,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QAC3D,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the live state of a single SPL token account (legacy SPL or
|
|
3
|
+
* Token-2022) over JSON-RPC and surface the bits Leash cares about for
|
|
4
|
+
* pre-flight diagnostics: holdings (`amount`), the SPL **delegate**, and the
|
|
5
|
+
* outstanding **delegated allowance**.
|
|
6
|
+
*
|
|
7
|
+
* The raw on-chain layout is parsed by the RPC's `jsonParsed` encoder, so we
|
|
8
|
+
* never have to ship a base58 / Borsh decoder here. Returns `null` when the
|
|
9
|
+
* account does not exist (uninitialised ATA) so callers can distinguish
|
|
10
|
+
* "truly empty" from "missing".
|
|
11
|
+
*
|
|
12
|
+
* Used by `@leashmarket/buyer-kit` to reclassify a generic facilitator
|
|
13
|
+
* `transaction_simulation` failure into a precise
|
|
14
|
+
* `insufficient_balance` / `insufficient_allowance` / `no_delegate`
|
|
15
|
+
* verdict on the resulting receipt.
|
|
16
|
+
*/
|
|
17
|
+
export type SplTokenAccountState = {
|
|
18
|
+
/** The token account address that was inspected. */
|
|
19
|
+
address: string;
|
|
20
|
+
/** SPL mint this account holds. */
|
|
21
|
+
mint: string;
|
|
22
|
+
/** On-chain owner of the token account (treasury PDA, wallet, etc.). */
|
|
23
|
+
owner: string;
|
|
24
|
+
/** Holdings in atomic units (e.g. `5_000_000n` for 5 USDC at 6 decimals). */
|
|
25
|
+
amount: bigint;
|
|
26
|
+
/** SPL token decimals as reported by the RPC's parsed encoding. */
|
|
27
|
+
decimals: number;
|
|
28
|
+
/** SPL delegate address (the authority approved to spend), or `null`. */
|
|
29
|
+
delegate: string | null;
|
|
30
|
+
/** Outstanding allowance in atomic units. `0n` when no delegate is set. */
|
|
31
|
+
delegatedAmount: bigint;
|
|
32
|
+
/** Which token program owns this account (matters for instruction encoding). */
|
|
33
|
+
program: 'spl-token' | 'spl-token-2022' | 'unknown';
|
|
34
|
+
};
|
|
35
|
+
export type InspectSplTokenAccountOptions = {
|
|
36
|
+
rpcUrl: string;
|
|
37
|
+
/** The token account address (an ATA, typically). */
|
|
38
|
+
address: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Returns the parsed state of `address` or `null` if the account does not
|
|
42
|
+
* exist on-chain. Throws on RPC transport errors (so callers can decide
|
|
43
|
+
* whether to surface a degraded-mode warning vs. fail open).
|
|
44
|
+
*/
|
|
45
|
+
export declare function inspectSplTokenAccount(opts: InspectSplTokenAccountOptions): Promise<SplTokenAccountState | null>;
|
|
46
|
+
//# sourceMappingURL=inspect-token-account.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-token-account.d.ts","sourceRoot":"","sources":["../../src/treasury/inspect-token-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,oBAAoB,GAAG;IACjC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2EAA2E;IAC3E,eAAe,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,OAAO,EAAE,WAAW,GAAG,gBAAgB,GAAG,SAAS,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAoBF;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA2BtC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the live state of a single SPL token account (legacy SPL or
|
|
3
|
+
* Token-2022) over JSON-RPC and surface the bits Leash cares about for
|
|
4
|
+
* pre-flight diagnostics: holdings (`amount`), the SPL **delegate**, and the
|
|
5
|
+
* outstanding **delegated allowance**.
|
|
6
|
+
*
|
|
7
|
+
* The raw on-chain layout is parsed by the RPC's `jsonParsed` encoder, so we
|
|
8
|
+
* never have to ship a base58 / Borsh decoder here. Returns `null` when the
|
|
9
|
+
* account does not exist (uninitialised ATA) so callers can distinguish
|
|
10
|
+
* "truly empty" from "missing".
|
|
11
|
+
*
|
|
12
|
+
* Used by `@leashmarket/buyer-kit` to reclassify a generic facilitator
|
|
13
|
+
* `transaction_simulation` failure into a precise
|
|
14
|
+
* `insufficient_balance` / `insufficient_allowance` / `no_delegate`
|
|
15
|
+
* verdict on the resulting receipt.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Returns the parsed state of `address` or `null` if the account does not
|
|
19
|
+
* exist on-chain. Throws on RPC transport errors (so callers can decide
|
|
20
|
+
* whether to surface a degraded-mode warning vs. fail open).
|
|
21
|
+
*/
|
|
22
|
+
export async function inspectSplTokenAccount(opts) {
|
|
23
|
+
const result = await rpc(opts.rpcUrl, 'getAccountInfo', [
|
|
24
|
+
opts.address,
|
|
25
|
+
{ encoding: 'jsonParsed', commitment: 'confirmed' },
|
|
26
|
+
]);
|
|
27
|
+
if (!result.value)
|
|
28
|
+
return null;
|
|
29
|
+
const parsed = result.value.data.parsed;
|
|
30
|
+
// Only token accounts have `parsed.type === 'account'`. Anything else
|
|
31
|
+
// (mint accounts, plain wallets, etc.) is not what callers asked for.
|
|
32
|
+
if (parsed.type !== 'account')
|
|
33
|
+
return null;
|
|
34
|
+
const info = parsed.info;
|
|
35
|
+
const programLabel = result.value.data.program === 'spl-token'
|
|
36
|
+
? 'spl-token'
|
|
37
|
+
: result.value.data.program === 'spl-token-2022'
|
|
38
|
+
? 'spl-token-2022'
|
|
39
|
+
: 'unknown';
|
|
40
|
+
return {
|
|
41
|
+
address: opts.address,
|
|
42
|
+
mint: info.mint,
|
|
43
|
+
owner: info.owner,
|
|
44
|
+
amount: BigInt(info.tokenAmount.amount),
|
|
45
|
+
decimals: info.tokenAmount.decimals,
|
|
46
|
+
delegate: info.delegate ?? null,
|
|
47
|
+
delegatedAmount: info.delegatedAmount ? BigInt(info.delegatedAmount.amount) : 0n,
|
|
48
|
+
program: programLabel,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function rpc(rpcUrl, method, params) {
|
|
52
|
+
const res = await fetch(rpcUrl, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: { 'content-type': 'application/json' },
|
|
55
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
|
|
56
|
+
cache: 'no-store',
|
|
57
|
+
});
|
|
58
|
+
if (!res.ok)
|
|
59
|
+
throw new Error(`RPC ${method} HTTP ${res.status}`);
|
|
60
|
+
const json = (await res.json());
|
|
61
|
+
if (json.error)
|
|
62
|
+
throw new Error(`RPC ${method}: ${json.error.message}`);
|
|
63
|
+
if (json.result === undefined)
|
|
64
|
+
throw new Error(`RPC ${method}: empty result`);
|
|
65
|
+
return json.result;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=inspect-token-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-token-account.js","sourceRoot":"","sources":["../../src/treasury/inspect-token-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA6CH;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAmC;IAEnC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAkC,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE;QACvF,IAAI,CAAC,OAAO;QACZ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE;KACpD,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;IACxC,sEAAsE;IACtE,sEAAsE;IACtE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,YAAY,GAChB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,WAAW;QACvC,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,gBAAgB;YAC9C,CAAC,CAAC,gBAAgB;YAClB,CAAC,CAAC,SAAS,CAAC;IAClB,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QACvC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;QACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;QAC/B,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;QAChF,OAAO,EAAE,YAAY;KACtB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,GAAG,CAAI,MAAc,EAAE,MAAc,EAAE,MAAiB;IACrE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;QAC9B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/D,KAAK,EAAE,UAAU;KACkB,CAAC,CAAC;IACvC,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgD,CAAC;IAC/E,IAAI,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,gBAAgB,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumerate every SPL token an owner holds (legacy SPL + Token-2022),
|
|
3
|
+
* enrich with metadata from the {@link KNOWN_TOKENS} registry, and pin
|
|
4
|
+
* stablecoin entries with zero balance when missing so UI surfaces always
|
|
5
|
+
* render them.
|
|
6
|
+
*
|
|
7
|
+
* This consolidates logic that previously lived in
|
|
8
|
+
* `apps/playground/app/api/agents/balance/route.ts` and
|
|
9
|
+
* `apps/playground/app/api/wallet/balance/route.ts`. Calling it from the SDK means
|
|
10
|
+
* any future Leash surface (CLI, mobile, downstream agents) gets the same
|
|
11
|
+
* canonical balance shape without re-implementing the RPC plumbing.
|
|
12
|
+
*/
|
|
13
|
+
import { KNOWN_TOKENS, type TokenNetwork } from '../tokens/index.js';
|
|
14
|
+
export type SplTokenBalance = {
|
|
15
|
+
mint: string;
|
|
16
|
+
symbol: string | null;
|
|
17
|
+
name: string | null;
|
|
18
|
+
decimals: number;
|
|
19
|
+
/** Atomic integer string (e.g. `"1500000"` for 1.5 USDC). */
|
|
20
|
+
amount: string;
|
|
21
|
+
/** UI decimal as a number — best-effort, lossy for very large amounts. */
|
|
22
|
+
ui: number;
|
|
23
|
+
program: 'spl-token' | 'spl-token-2022';
|
|
24
|
+
/** True when the mint is in {@link KNOWN_TOKENS} for the requested network. */
|
|
25
|
+
known: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type ListSplBalancesOptions = {
|
|
28
|
+
/** Owner address (a wallet, an agent treasury PDA, etc.). */
|
|
29
|
+
owner: string;
|
|
30
|
+
/** Solana RPC endpoint to query. */
|
|
31
|
+
rpcUrl: string;
|
|
32
|
+
/** Logical network bucket — controls which mints get pinned. */
|
|
33
|
+
network: TokenNetwork;
|
|
34
|
+
/**
|
|
35
|
+
* If true, include stable-coin mints from {@link KNOWN_TOKENS} with zero
|
|
36
|
+
* balance when the owner doesn't hold them. Defaults to `true`. Disable
|
|
37
|
+
* for callers that want a strict on-chain view (e.g. analytics).
|
|
38
|
+
*/
|
|
39
|
+
pinKnownStables?: boolean;
|
|
40
|
+
};
|
|
41
|
+
export type ListSplBalancesResult = {
|
|
42
|
+
owner: string;
|
|
43
|
+
network: TokenNetwork;
|
|
44
|
+
/** SOL balance as decimal (lossy for large balances; see `lamports`). */
|
|
45
|
+
sol: number;
|
|
46
|
+
/** Raw lamport count as a string (lossless). */
|
|
47
|
+
lamports: string;
|
|
48
|
+
tokens: SplTokenBalance[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Enumerate balances. Tolerates RPC failures on either token program — if
|
|
52
|
+
* Token-2022 calls fail (some RPCs lag here), the function still returns
|
|
53
|
+
* legacy SPL balances rather than throwing.
|
|
54
|
+
*/
|
|
55
|
+
export declare function listSplBalances(opts: ListSplBalancesOptions): Promise<ListSplBalancesResult>;
|
|
56
|
+
export { KNOWN_TOKENS };
|
|
57
|
+
//# sourceMappingURL=list-balances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-balances.d.ts","sourceRoot":"","sources":["../../src/treasury/list-balances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,YAAY,EAMZ,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,GAAG,gBAAgB,CAAC;IACxC,+EAA+E;IAC/E,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,OAAO,EAAE,YAAY,CAAC;IACtB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;IACtB,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,qBAAqB,CAAC,CA6ChC;AAsFD,OAAO,EAAE,YAAY,EAAE,CAAC"}
|