@1sat/permission-module 0.0.49 → 0.0.51
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/dist/apply.d.ts +1 -1
- package/dist/apply.d.ts.map +1 -1
- package/dist/apply.js +3 -3
- package/dist/apply.js.map +1 -1
- package/dist/apply.test.js +29 -29
- package/dist/apply.test.js.map +1 -1
- package/dist/basketAccess.d.ts +38 -0
- package/dist/basketAccess.d.ts.map +1 -0
- package/dist/basketAccess.js +237 -0
- package/dist/basketAccess.js.map +1 -0
- package/dist/buildPromptIntent.d.ts +15 -0
- package/dist/buildPromptIntent.d.ts.map +1 -0
- package/dist/buildPromptIntent.js +575 -0
- package/dist/buildPromptIntent.js.map +1 -0
- package/dist/createOneSatPermissionModule.d.ts +10 -5
- package/dist/createOneSatPermissionModule.d.ts.map +1 -1
- package/dist/createOneSatPermissionModule.js +28 -6
- package/dist/createOneSatPermissionModule.js.map +1 -1
- package/dist/enrichIntent.d.ts +121 -5
- package/dist/enrichIntent.d.ts.map +1 -1
- package/dist/enrichIntent.js +576 -137
- package/dist/enrichIntent.js.map +1 -1
- package/dist/handlers.d.ts +12 -32
- package/dist/handlers.d.ts.map +1 -1
- package/dist/handlers.js +120 -155
- package/dist/handlers.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/listOutputsScope.test.d.ts +2 -0
- package/dist/listOutputsScope.test.d.ts.map +1 -0
- package/dist/listOutputsScope.test.js +116 -0
- package/dist/listOutputsScope.test.js.map +1 -0
- package/dist/promptModel.d.ts +115 -0
- package/dist/promptModel.d.ts.map +1 -0
- package/dist/promptModel.js +7 -0
- package/dist/promptModel.js.map +1 -0
- package/dist/types.d.ts +36 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/verifyIntent.d.ts +4 -4
- package/dist/verifyIntent.d.ts.map +1 -1
- package/dist/verifyIntent.js +120 -40
- package/dist/verifyIntent.js.map +1 -1
- package/dist/viewScope.d.ts +51 -0
- package/dist/viewScope.d.ts.map +1 -0
- package/dist/viewScope.js +113 -0
- package/dist/viewScope.js.map +1 -0
- package/dist/viewScope.test.d.ts +2 -0
- package/dist/viewScope.test.d.ts.map +1 -0
- package/dist/viewScope.test.js +60 -0
- package/dist/viewScope.test.js.map +1 -0
- package/package.json +42 -42
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { handleListOutputsRequest } from './basketAccess';
|
|
3
|
+
import { CommitmentCache } from './commitmentCache';
|
|
4
|
+
function mockStore() {
|
|
5
|
+
const map = new Map();
|
|
6
|
+
const keyOf = (k) => `${k.type}|${k.originator}|${k.basket ?? ''}`;
|
|
7
|
+
return {
|
|
8
|
+
async findGrant(key) {
|
|
9
|
+
const g = map.get(keyOf(key));
|
|
10
|
+
return g
|
|
11
|
+
? {
|
|
12
|
+
key,
|
|
13
|
+
expiry: g.expiry,
|
|
14
|
+
grantedAt: 0,
|
|
15
|
+
}
|
|
16
|
+
: null;
|
|
17
|
+
},
|
|
18
|
+
async putGrant(grant) {
|
|
19
|
+
map.set(keyOf(grant.key), { expiry: grant.expiry });
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function deps(opts) {
|
|
24
|
+
return {
|
|
25
|
+
wallet: {},
|
|
26
|
+
promptHandler: opts.promptHandler ?? (async () => true),
|
|
27
|
+
cache: new CommitmentCache(60),
|
|
28
|
+
schemeId: '1sat',
|
|
29
|
+
ownedBaskets: new Set(['1sat']),
|
|
30
|
+
adminOriginator: opts.adminOriginator,
|
|
31
|
+
permissionStore: opts.permissionStore,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const COLL = 'collection:a1b2c3d4e5f6070890abcdef1234567890abcdef1234567890abcdef12345678_0';
|
|
35
|
+
describe('handleListOutputsRequest scopes', () => {
|
|
36
|
+
test('rejects bare p 1sat', async () => {
|
|
37
|
+
await expect(handleListOutputsRequest(deps({}), { basket: 'p 1sat' }, 'app.example')).rejects.toThrow(/requires a scope/);
|
|
38
|
+
});
|
|
39
|
+
test('rejects collection scope without axis tag', async () => {
|
|
40
|
+
await expect(handleListOutputsRequest(deps({}), { basket: 'p 1sat collection' }, 'app.example')).rejects.toThrow(/requires at least one collection:/);
|
|
41
|
+
});
|
|
42
|
+
test('normalizes collection scope; keeps tags; forces all', async () => {
|
|
43
|
+
const next = await handleListOutputsRequest(deps({ promptHandler: async () => true }), {
|
|
44
|
+
basket: 'p 1sat collection',
|
|
45
|
+
tags: [COLL, 'type:image/png'],
|
|
46
|
+
tagQueryMode: 'any',
|
|
47
|
+
}, 'app.example');
|
|
48
|
+
expect(next.basket).toBe('1sat');
|
|
49
|
+
expect(next.tags).toEqual([COLL, 'type:image/png']);
|
|
50
|
+
expect(next.tagQueryMode).toBe('all');
|
|
51
|
+
});
|
|
52
|
+
test('p 1sat all does not require axis tags', async () => {
|
|
53
|
+
const next = await handleListOutputsRequest(deps({ promptHandler: async () => true }), {
|
|
54
|
+
basket: 'p 1sat all',
|
|
55
|
+
tags: ['type:image/png'],
|
|
56
|
+
tagQueryMode: 'any',
|
|
57
|
+
}, 'app.example');
|
|
58
|
+
expect(next.basket).toBe('1sat');
|
|
59
|
+
expect(next.tags).toEqual(['type:image/png']);
|
|
60
|
+
expect(next.tagQueryMode).toBe('any');
|
|
61
|
+
});
|
|
62
|
+
test('admin skips prompt', async () => {
|
|
63
|
+
let prompted = false;
|
|
64
|
+
await handleListOutputsRequest(deps({
|
|
65
|
+
adminOriginator: 'admin.local',
|
|
66
|
+
promptHandler: async () => {
|
|
67
|
+
prompted = true;
|
|
68
|
+
return true;
|
|
69
|
+
},
|
|
70
|
+
}), { basket: 'p 1sat all' }, 'admin.local');
|
|
71
|
+
expect(prompted).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
test('p 1sat id auto-allows without view grant prompt', async () => {
|
|
74
|
+
let prompted = false;
|
|
75
|
+
const next = await handleListOutputsRequest(deps({
|
|
76
|
+
promptHandler: async () => {
|
|
77
|
+
prompted = true;
|
|
78
|
+
return true;
|
|
79
|
+
},
|
|
80
|
+
}), {
|
|
81
|
+
basket: 'p 1sat id',
|
|
82
|
+
tags: ['id:abc123'],
|
|
83
|
+
}, 'app.example');
|
|
84
|
+
expect(prompted).toBe(false);
|
|
85
|
+
expect(next.basket).toBe('1sat');
|
|
86
|
+
expect(next.tags).toEqual(['id:abc123']);
|
|
87
|
+
expect(next.tagQueryMode).toBe('all');
|
|
88
|
+
});
|
|
89
|
+
test('p 1sat id requires id: tag', async () => {
|
|
90
|
+
await expect(handleListOutputsRequest(deps({}), { basket: 'p 1sat id' }, 'app.example')).rejects.toThrow(/requires at least one id:/);
|
|
91
|
+
});
|
|
92
|
+
test('collection grant is per tag value', async () => {
|
|
93
|
+
const prompts = [];
|
|
94
|
+
const d = deps({
|
|
95
|
+
permissionStore: mockStore(),
|
|
96
|
+
promptHandler: async (req) => {
|
|
97
|
+
if (req.kind === 'basketAccess') {
|
|
98
|
+
const baskets = req.payload.baskets;
|
|
99
|
+
prompts.push(baskets.map((b) => b.basket));
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
const collB = 'collection:b1b2c3d4e5f6070890abcdef1234567890abcdef1234567890abcdef12345678_0';
|
|
105
|
+
await handleListOutputsRequest(d, { basket: 'p 1sat collection', tags: [COLL] }, 'app.example');
|
|
106
|
+
expect(prompts).toHaveLength(1);
|
|
107
|
+
expect(prompts[0][0]).toContain('a1b2c3d4');
|
|
108
|
+
prompts.length = 0;
|
|
109
|
+
await handleListOutputsRequest(d, { basket: 'p 1sat collection', tags: [COLL] }, 'app.example');
|
|
110
|
+
expect(prompts).toHaveLength(0);
|
|
111
|
+
await handleListOutputsRequest(d, { basket: 'p 1sat collection', tags: [collB] }, 'app.example');
|
|
112
|
+
expect(prompts).toHaveLength(1);
|
|
113
|
+
expect(prompts[0][0]).toContain('b1b2c3d4');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=listOutputsScope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listOutputsScope.test.js","sourceRoot":"","sources":["../src/listOutputsScope.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { TrustState } from './enrichIntent';
|
|
2
|
+
/**
|
|
3
|
+
* Serializable prompt IR.
|
|
4
|
+
*
|
|
5
|
+
* Built once in the permission module after parse/enrich. The UI only renders
|
|
6
|
+
* these fields — it does not re-classify scripts, tags, or baskets.
|
|
7
|
+
*/
|
|
8
|
+
export type PreviewKind = 'image' | 'text' | 'json' | 'html' | 'svg' | 'opns' | 'none';
|
|
9
|
+
export type PanelVariant = 'ordinal' | 'token' | 'value';
|
|
10
|
+
/** Visual tone — burn panels use danger. */
|
|
11
|
+
export type PanelTone = 'default' | 'danger';
|
|
12
|
+
export type ValueIcon = 'lock' | 'unlock' | 'pay';
|
|
13
|
+
/** One labeled detail line under a panel title. */
|
|
14
|
+
export interface PromptDetailRow {
|
|
15
|
+
key: string;
|
|
16
|
+
/** Display value (may be shortened for addresses/origins). */
|
|
17
|
+
value: string;
|
|
18
|
+
/** Full string for clipboard when shortened. */
|
|
19
|
+
copyValue?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One self-contained card block (ordinal edge, lock/pay, token, …).
|
|
23
|
+
* Media and action copy are settled before this crosses the wire.
|
|
24
|
+
*/
|
|
25
|
+
export interface PromptPanel {
|
|
26
|
+
title: string;
|
|
27
|
+
subtitle?: string;
|
|
28
|
+
subtitleCopy?: string;
|
|
29
|
+
meta?: PromptDetailRow[];
|
|
30
|
+
variant?: PanelVariant;
|
|
31
|
+
previewKind?: PreviewKind;
|
|
32
|
+
/** Image / avatar URL when preview is image or opns avatar. */
|
|
33
|
+
imageUrl?: string;
|
|
34
|
+
/** Fetch URL for text/json/html/svg previews. */
|
|
35
|
+
contentUrl?: string;
|
|
36
|
+
/** Inline body when the script was decoded (mint / no OrdFS URL yet). */
|
|
37
|
+
previewText?: string;
|
|
38
|
+
/** Full sat amount for value panels — never truncated in the UI. */
|
|
39
|
+
amountSats?: number;
|
|
40
|
+
valueIcon?: ValueIcon;
|
|
41
|
+
/** OpNS profile name shown as hero text when previewKind is opns. */
|
|
42
|
+
opnsHero?: string;
|
|
43
|
+
/** Burn / destructive ops — subtle danger chrome. */
|
|
44
|
+
tone?: PanelTone;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Reserved for admin pre-fund (BRC-29 payment UTXOs applied before prompt).
|
|
48
|
+
* Omit until pre-fund lands — structure is here so panels are not ordinal-only.
|
|
49
|
+
*/
|
|
50
|
+
export interface PromptFunding {
|
|
51
|
+
networkFeeSats?: number;
|
|
52
|
+
fundingInputSats?: number;
|
|
53
|
+
changeSats?: number;
|
|
54
|
+
note?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Overlay/indexer fee (not miner fee). */
|
|
57
|
+
export interface PromptIndexerFee {
|
|
58
|
+
sats: number;
|
|
59
|
+
note?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface PromptTrust {
|
|
62
|
+
state: TrustState;
|
|
63
|
+
note?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Facts verifyIntent needs without the UI re-deriving them from tags.
|
|
67
|
+
* Optional — only purchases/hint paths set trust + verify.
|
|
68
|
+
*/
|
|
69
|
+
export interface PromptVerifyContext {
|
|
70
|
+
kind: string;
|
|
71
|
+
inputs: Array<{
|
|
72
|
+
basket: string;
|
|
73
|
+
id: string;
|
|
74
|
+
outpoint: string;
|
|
75
|
+
satoshis: number;
|
|
76
|
+
tags: string[];
|
|
77
|
+
/** Case-preserving fields (sym, name) — tags are lowercased by BRC-100. */
|
|
78
|
+
customInstructions?: string;
|
|
79
|
+
}>;
|
|
80
|
+
outputs: Array<{
|
|
81
|
+
index: number;
|
|
82
|
+
satoshis: number;
|
|
83
|
+
basket?: string;
|
|
84
|
+
tags: string[];
|
|
85
|
+
recipient?: string;
|
|
86
|
+
listingPriceSats?: number;
|
|
87
|
+
}>;
|
|
88
|
+
contentUrls?: Record<string, string>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Transaction prompt payload (`PromptRequest.kind === 'transaction'`).
|
|
92
|
+
* Pure data — no functions, safe across process boundaries.
|
|
93
|
+
*/
|
|
94
|
+
/**
|
|
95
|
+
* Serializable transaction approval view: title, panels, fees.
|
|
96
|
+
* Not a classification taxonomy — pure display IR from one parse.
|
|
97
|
+
*/
|
|
98
|
+
export interface TransactionPrompt {
|
|
99
|
+
/** Header title — currently always "Transaction Request". */
|
|
100
|
+
title: string;
|
|
101
|
+
/** Header subtitle — originator line. */
|
|
102
|
+
subtitle: string;
|
|
103
|
+
/** Primary body: one panel per op (ordinal edge, lock, pay, …). */
|
|
104
|
+
panels: PromptPanel[];
|
|
105
|
+
/** Secondary lines that are not full panels (leftover seals, etc.). */
|
|
106
|
+
rows: PromptDetailRow[];
|
|
107
|
+
trust?: PromptTrust;
|
|
108
|
+
indexerFee?: PromptIndexerFee;
|
|
109
|
+
/** Present after pre-fund; reserved until then. */
|
|
110
|
+
funding?: PromptFunding;
|
|
111
|
+
/** Purchase verification context for the host UI. */
|
|
112
|
+
verify?: PromptVerifyContext;
|
|
113
|
+
}
|
|
114
|
+
export declare function isTransactionPrompt(value: unknown): value is TransactionPrompt;
|
|
115
|
+
//# sourceMappingURL=promptModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptModel.d.ts","sourceRoot":"","sources":["../src/promptModel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptModel.js","sourceRoot":"","sources":["../src/promptModel.ts"],"names":[],"mappings":"AAqIA,MAAM,UAAU,mBAAmB,CAClC,KAAc;IAEd,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACrD,MAAM,CAAC,GAAG,KAAgC,CAAA;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAA;AAC9D,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PermissionSchemeId } from '@1sat/types';
|
|
1
2
|
import type { IPermissionStore } from '@1sat/wallet';
|
|
2
3
|
import type { WalletInterface } from '@bsv/sdk';
|
|
3
4
|
/**
|
|
@@ -33,17 +34,13 @@ export interface PromptRequest {
|
|
|
33
34
|
kind: PromptKind;
|
|
34
35
|
originator: string;
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
+
* Host UI data.
|
|
37
38
|
*
|
|
38
|
-
* Transaction
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* - `trust?` — `{ state: 'verified'|'unverified'|'mismatch', note? }` purchases
|
|
42
|
-
* - `indexerFeeSats?` / `indexerFeeNote?` — overlay fee (not miner/DSAP)
|
|
43
|
-
*
|
|
44
|
-
* For `kind: 'basketAccess'`: `{ baskets: BasketAccessRequest[] }`.
|
|
39
|
+
* Transaction: {@link import('./promptModel').TransactionPrompt}
|
|
40
|
+
* (panels already built — UI only renders).
|
|
41
|
+
* basketAccess: `{ baskets: BasketAccessRequest[] }`.
|
|
45
42
|
*/
|
|
46
|
-
|
|
43
|
+
payload: Record<string, unknown>;
|
|
47
44
|
/** Short human-readable summary line. Filled in by the module. */
|
|
48
45
|
summary: string;
|
|
49
46
|
}
|
|
@@ -52,8 +49,17 @@ export interface PromptRequest {
|
|
|
52
49
|
* `kind: 'basketAccess'` prompt intent.
|
|
53
50
|
*/
|
|
54
51
|
export interface BasketAccessRequest {
|
|
52
|
+
/** Grant key (e.g. `p 1sat collection <id>` or plain `1sat`). */
|
|
55
53
|
basket: string;
|
|
56
54
|
description?: string;
|
|
55
|
+
/** View axis when this is a scoped grant (`collection` / `app` / `creator` / `all`). */
|
|
56
|
+
scope?: string;
|
|
57
|
+
/** Axis filter value (e.g. collection outpoint). Always show when set. */
|
|
58
|
+
value?: string;
|
|
59
|
+
/** Optional display name (e.g. OrdFS MAP name for a collection). */
|
|
60
|
+
name?: string;
|
|
61
|
+
/** Optional preview image URL (OrdFS content). */
|
|
62
|
+
imageUrl?: string;
|
|
57
63
|
}
|
|
58
64
|
/**
|
|
59
65
|
* Callback the host wallet provides for showing prompts and awaiting
|
|
@@ -93,14 +99,24 @@ export interface VerificationServices {
|
|
|
93
99
|
token?: {
|
|
94
100
|
sym?: string;
|
|
95
101
|
dec?: string | number;
|
|
102
|
+
icon?: string;
|
|
96
103
|
};
|
|
97
104
|
status?: {
|
|
98
105
|
is_active?: boolean;
|
|
99
106
|
};
|
|
100
107
|
} | null>;
|
|
108
|
+
/**
|
|
109
|
+
* Validate outpoints against the token overlay topic.
|
|
110
|
+
* Returns only those found (optionally unspent).
|
|
111
|
+
*/
|
|
112
|
+
validateOutputs?(tokenId: string, outpoints: string[], opts?: {
|
|
113
|
+
unspent?: boolean;
|
|
114
|
+
}): Promise<Array<{
|
|
115
|
+
outpoint: string;
|
|
116
|
+
}>>;
|
|
101
117
|
};
|
|
102
118
|
}
|
|
103
|
-
/** Args accepted by `createOneSatPermissionModule
|
|
119
|
+
/** Args accepted by `createOneSatPermissionModule` / scheme modules. */
|
|
104
120
|
export interface CreateOneSatPermissionModuleArgs {
|
|
105
121
|
/**
|
|
106
122
|
* The underlying wallet (NOT the WalletPermissionsManager wrapper).
|
|
@@ -110,6 +126,16 @@ export interface CreateOneSatPermissionModuleArgs {
|
|
|
110
126
|
wallet: WalletInterface;
|
|
111
127
|
/** UI callback for prompting the user. */
|
|
112
128
|
promptHandler: PromptHandler;
|
|
129
|
+
/**
|
|
130
|
+
* BRC-99 scheme id this module instance handles (e.g. `1sat`, `opns`, `bsv21`).
|
|
131
|
+
* Default `1sat`.
|
|
132
|
+
*/
|
|
133
|
+
schemeId?: PermissionSchemeId;
|
|
134
|
+
/**
|
|
135
|
+
* Storage baskets this module may gate on list/internalize.
|
|
136
|
+
* Default: `[schemeId]` (scheme id === basket name).
|
|
137
|
+
*/
|
|
138
|
+
baskets?: readonly string[];
|
|
113
139
|
/**
|
|
114
140
|
* Optional persistent grant store consulted before prompting for
|
|
115
141
|
* basket-access on P-baskets. Same `IPermissionStore` instance the
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,KAAK,CAAA;AAEhD,iEAAiE;AACjE,MAAM,WAAW,kBAAkB;IAClC,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAA;IACnB,+DAA+D;IAC/D,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,CAAA;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,CAAA"}
|
package/dist/verifyIntent.d.ts
CHANGED
|
@@ -8,8 +8,6 @@ export interface VerificationResult {
|
|
|
8
8
|
note?: string;
|
|
9
9
|
/** Content type confirmed by ORDFS, when it answered. */
|
|
10
10
|
contentType?: string;
|
|
11
|
-
/** Content length in bytes confirmed by ORDFS, when it answered. */
|
|
12
|
-
contentLength?: number;
|
|
13
11
|
/**
|
|
14
12
|
* True origin as resolved by ORDFS.
|
|
15
13
|
*
|
|
@@ -24,10 +22,12 @@ export interface VerificationResult {
|
|
|
24
22
|
contentUrl?: string;
|
|
25
23
|
}
|
|
26
24
|
/**
|
|
27
|
-
* Verify
|
|
25
|
+
* Verify assets on a purchase or BSV21 transfer.
|
|
28
26
|
*
|
|
29
27
|
* Returns `unverified` for anything we cannot positively confirm, including
|
|
30
28
|
* when no services are wired at all. Never throws.
|
|
31
29
|
*/
|
|
32
|
-
export declare function verifyIntent(services: VerificationServices | undefined,
|
|
30
|
+
export declare function verifyIntent(services: VerificationServices | undefined,
|
|
31
|
+
/** Prompt kind from script/heuristic classify, or legacy intent id. */
|
|
32
|
+
kindOrIntent: string | undefined, inputs: EnrichedAsset[], outputs: EnrichedOutput[], contentUrlForOrigin?: (origin: string) => string): Promise<VerificationResult>;
|
|
33
33
|
//# sourceMappingURL=verifyIntent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyIntent.d.ts","sourceRoot":"","sources":["../src/verifyIntent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verifyIntent.d.ts","sourceRoot":"","sources":["../src/verifyIntent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAE3C,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,UAAU,CAAA;IACjB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAyKD;;;;;GAKG;AACH,wBAAsB,YAAY,CACjC,QAAQ,EAAE,oBAAoB,GAAG,SAAS;AAC1C,uEAAuE;AACvE,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,EAAE,cAAc,EAAE,EACzB,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAC9C,OAAO,CAAC,kBAAkB,CAAC,CA4G7B"}
|
package/dist/verifyIntent.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatOrdinalOutpoint } from '@1sat/types';
|
|
1
2
|
/** How long any single verification lookup may take before it is abandoned. */
|
|
2
3
|
export const VERIFICATION_TIMEOUT_MS = 2000;
|
|
3
4
|
/**
|
|
@@ -36,21 +37,21 @@ async function verifyOrdinal(services, origin, claimedTypes = []) {
|
|
|
36
37
|
const ordfs = services.ordfs;
|
|
37
38
|
if (typeof ordfs?.bulkMetadata !== 'function')
|
|
38
39
|
return { state: 'unverified' };
|
|
39
|
-
// `:-2`
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
// record rather than the asset.
|
|
40
|
+
// `:-2` is only an ORDFS request suffix (resolve tip → origin metadata).
|
|
41
|
+
// It is not part of asset identity and must not be required to match
|
|
42
|
+
// response map keys beyond looking up the bulk result.
|
|
43
43
|
const key = `${origin}:-2`;
|
|
44
|
-
// Called on the client, not detached — these are class methods that use `this`.
|
|
45
44
|
const res = await withTimeout(ordfs.bulkMetadata([key]));
|
|
46
|
-
|
|
45
|
+
// Prefer exact key, then bare origin, then any record that carried content.
|
|
46
|
+
const meta = res?.[key] ??
|
|
47
|
+
res?.[origin] ??
|
|
48
|
+
Object.values(res ?? {}).find((m) => !!m?.contentType);
|
|
47
49
|
// An empty record means "nothing inscribed here", not a description of the
|
|
48
50
|
// asset — treat it as no answer rather than as evidence.
|
|
49
51
|
if (!meta?.contentType)
|
|
50
52
|
return { state: 'unverified' };
|
|
51
53
|
const resolved = {
|
|
52
54
|
contentType: meta.contentType,
|
|
53
|
-
contentLength: meta.contentLength,
|
|
54
55
|
// ORDFS resolves the true genesis; the tagged value is usually the
|
|
55
56
|
// seller's listing outpoint. Not treated as a mismatch — the claimed
|
|
56
57
|
// value is an outpoint by construction, not a competing assertion.
|
|
@@ -86,8 +87,11 @@ async function verifyOpns(services, name, origin) {
|
|
|
86
87
|
}
|
|
87
88
|
return { state: 'verified' };
|
|
88
89
|
}
|
|
89
|
-
/**
|
|
90
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Verify a BSV21 token is active and that spent inputs are valid unspent
|
|
92
|
+
* outs on the token overlay topic.
|
|
93
|
+
*/
|
|
94
|
+
async function verifyBsv21(services, tokenId, claimedSym, inputOutpoints = []) {
|
|
91
95
|
const bsv21 = services.bsv21;
|
|
92
96
|
if (typeof bsv21?.getTokenDetails !== 'function')
|
|
93
97
|
return { state: 'unverified' };
|
|
@@ -98,20 +102,60 @@ async function verifyBsv21(services, tokenId, claimedSym) {
|
|
|
98
102
|
return { state: 'mismatch', note: 'Token is not active on the overlay' };
|
|
99
103
|
}
|
|
100
104
|
const sym = res.token?.sym;
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
// Tags are lowercased by BRC-100; CI/overlay preserve case — compare ignore-case.
|
|
106
|
+
if (claimedSym &&
|
|
107
|
+
sym &&
|
|
108
|
+
claimedSym.toLowerCase() !== sym.toLowerCase()) {
|
|
109
|
+
return {
|
|
110
|
+
state: 'mismatch',
|
|
111
|
+
note: `Token symbol is ${sym}, not ${claimedSym}`,
|
|
112
|
+
};
|
|
103
113
|
}
|
|
104
|
-
|
|
114
|
+
// Validate spent token UTXOs against the overlay (same check sendBsv21 uses).
|
|
115
|
+
if (inputOutpoints.length > 0 && typeof bsv21.validateOutputs === 'function') {
|
|
116
|
+
const validated = await withTimeout(bsv21.validateOutputs(tokenId, inputOutpoints, { unspent: true }));
|
|
117
|
+
if (!validated)
|
|
118
|
+
return { state: 'unverified' };
|
|
119
|
+
const ok = new Set(validated.map((v) => formatOrdinalOutpoint(v.outpoint)));
|
|
120
|
+
const missing = inputOutpoints.filter((op) => !ok.has(formatOrdinalOutpoint(op)));
|
|
121
|
+
if (missing.length > 0) {
|
|
122
|
+
return {
|
|
123
|
+
state: 'mismatch',
|
|
124
|
+
note: missing.length === 1
|
|
125
|
+
? 'A spent token output is not valid on the overlay'
|
|
126
|
+
: `${missing.length} spent token outputs are not valid on the overlay`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
state: 'verified',
|
|
132
|
+
// Case-preserving symbol from overlay for the card subtitle.
|
|
133
|
+
...(sym ? { name: sym } : {}),
|
|
134
|
+
};
|
|
105
135
|
}
|
|
106
136
|
/**
|
|
107
|
-
* Verify
|
|
137
|
+
* Verify assets on a purchase or BSV21 transfer.
|
|
108
138
|
*
|
|
109
139
|
* Returns `unverified` for anything we cannot positively confirm, including
|
|
110
140
|
* when no services are wired at all. Never throws.
|
|
111
141
|
*/
|
|
112
|
-
export async function verifyIntent(services,
|
|
113
|
-
|
|
142
|
+
export async function verifyIntent(services,
|
|
143
|
+
/** Prompt kind from script/heuristic classify, or legacy intent id. */
|
|
144
|
+
kindOrIntent, inputs, outputs, contentUrlForOrigin) {
|
|
145
|
+
if (!services || !kindOrIntent)
|
|
114
146
|
return { state: 'unverified' };
|
|
147
|
+
const isPurchase = kindOrIntent === 'purchase' || kindOrIntent.endsWith('.purchase');
|
|
148
|
+
const isTokenTransfer = kindOrIntent === 'token-transfer' ||
|
|
149
|
+
kindOrIntent.startsWith('bsv21.');
|
|
150
|
+
if (!isPurchase && !isTokenTransfer)
|
|
151
|
+
return { state: 'unverified' };
|
|
152
|
+
const debug = {
|
|
153
|
+
kindOrIntent,
|
|
154
|
+
hasOrdfs: !!services.ordfs,
|
|
155
|
+
hasBulk: typeof services.ordfs?.bulkMetadata === 'function',
|
|
156
|
+
inputTagSets: inputs.map((i) => i.tags),
|
|
157
|
+
outputTagSets: outputs.map((o) => o.tags),
|
|
158
|
+
};
|
|
115
159
|
try {
|
|
116
160
|
const allTags = [...inputs.map((i) => i.tags), ...outputs.map((o) => o.tags)];
|
|
117
161
|
const findAll = (key) => allTags.flatMap((tags) => tags
|
|
@@ -125,36 +169,72 @@ export async function verifyIntent(services, p1satIntent, inputs, outputs, conte
|
|
|
125
169
|
}
|
|
126
170
|
return undefined;
|
|
127
171
|
};
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
172
|
+
// BSV21: token active + spent inputs valid on overlay.
|
|
173
|
+
const tokenId = find('bsv21');
|
|
174
|
+
if (tokenId ||
|
|
175
|
+
kindOrIntent === 'bsv21.purchase' ||
|
|
176
|
+
kindOrIntent === 'token-transfer' ||
|
|
177
|
+
kindOrIntent.startsWith('bsv21.')) {
|
|
178
|
+
if (!tokenId)
|
|
179
|
+
return { state: 'unverified' };
|
|
180
|
+
const tokenInputs = inputs.filter((i) => i.basket?.includes('bsv21') ||
|
|
181
|
+
i.tags.some((t) => t.startsWith('bsv21:')));
|
|
182
|
+
const outpoints = tokenInputs
|
|
183
|
+
.map((i) => i.outpoint)
|
|
184
|
+
.filter(Boolean);
|
|
185
|
+
// Prefer case-preserving CI sym over lowercased tags.
|
|
186
|
+
let claimedSym = find('sym');
|
|
187
|
+
for (const inp of inputs) {
|
|
188
|
+
if (!inp.customInstructions)
|
|
189
|
+
continue;
|
|
190
|
+
try {
|
|
191
|
+
const s = JSON.parse(inp.customInstructions).sym;
|
|
192
|
+
if (typeof s === 'string' && s.trim()) {
|
|
193
|
+
claimedSym = s.trim();
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// ignore
|
|
199
|
+
}
|
|
139
200
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
201
|
+
return await verifyBsv21(services, tokenId, claimedSym, outpoints);
|
|
202
|
+
}
|
|
203
|
+
const name = find('name');
|
|
204
|
+
const origin = find('origin');
|
|
205
|
+
debug.name = name;
|
|
206
|
+
debug.origin = origin;
|
|
207
|
+
if ((name && origin && outputs.some((o) => o.basket?.includes('opns'))) ||
|
|
208
|
+
kindOrIntent === 'opns.purchase') {
|
|
209
|
+
if (!name || !origin)
|
|
210
|
+
return { state: 'unverified' };
|
|
211
|
+
return await verifyOpns(services, name, origin);
|
|
212
|
+
}
|
|
213
|
+
if (!origin) {
|
|
214
|
+
debug.reason = 'no-origin-tag';
|
|
215
|
+
globalThis.__lastVerify = debug;
|
|
216
|
+
return { state: 'unverified' };
|
|
217
|
+
}
|
|
218
|
+
const res = await verifyOrdinal(services, origin, findAll('type'));
|
|
219
|
+
debug.verifyOrdinal = res;
|
|
220
|
+
// contentUrl is optional polish — never let a URL helper wipe a verified result
|
|
221
|
+
// (e.g. unbound getContentUrl losing `this` and throwing).
|
|
222
|
+
if (res.origin && contentUrlForOrigin) {
|
|
223
|
+
try {
|
|
224
|
+
res.contentUrl = contentUrlForOrigin(res.origin);
|
|
146
225
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (!tokenId)
|
|
150
|
-
return { state: 'unverified' };
|
|
151
|
-
return await verifyBsv21(services, tokenId, find('sym'));
|
|
226
|
+
catch (e) {
|
|
227
|
+
debug.contentUrlError = String(e);
|
|
152
228
|
}
|
|
153
|
-
default:
|
|
154
|
-
return { state: 'unverified' };
|
|
155
229
|
}
|
|
230
|
+
;
|
|
231
|
+
globalThis.__lastVerify = debug;
|
|
232
|
+
return res;
|
|
156
233
|
}
|
|
157
|
-
catch {
|
|
234
|
+
catch (e) {
|
|
235
|
+
debug.error = String(e);
|
|
236
|
+
globalThis.__lastVerify =
|
|
237
|
+
debug;
|
|
158
238
|
return { state: 'unverified' };
|
|
159
239
|
}
|
|
160
240
|
}
|