@antseed/cli 0.1.168 → 0.1.169
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/buyer-identities/loader.d.ts +28 -0
- package/dist/buyer-identities/loader.d.ts.map +1 -0
- package/dist/buyer-identities/loader.js +58 -0
- package/dist/buyer-identities/loader.js.map +1 -0
- package/dist/buyer-identities/store.d.ts +41 -0
- package/dist/buyer-identities/store.d.ts.map +1 -0
- package/dist/buyer-identities/store.js +171 -0
- package/dist/buyer-identities/store.js.map +1 -0
- package/dist/buyer-identities/store.test.d.ts +2 -0
- package/dist/buyer-identities/store.test.d.ts.map +1 -0
- package/dist/buyer-identities/store.test.js +122 -0
- package/dist/buyer-identities/store.test.js.map +1 -0
- package/dist/cli/commands/buyer/identity.d.ts +3 -0
- package/dist/cli/commands/buyer/identity.d.ts.map +1 -0
- package/dist/cli/commands/buyer/identity.js +115 -0
- package/dist/cli/commands/buyer/identity.js.map +1 -0
- package/dist/cli/commands/buyer/index.d.ts.map +1 -1
- package/dist/cli/commands/buyer/index.js +2 -0
- package/dist/cli/commands/buyer/index.js.map +1 -1
- package/dist/cli/commands/buyer/start.d.ts.map +1 -1
- package/dist/cli/commands/buyer/start.js +30 -2
- package/dist/cli/commands/buyer/start.js.map +1 -1
- package/dist/cli/commands/gateway/index.d.ts +3 -0
- package/dist/cli/commands/gateway/index.d.ts.map +1 -0
- package/dist/cli/commands/gateway/index.js +43 -0
- package/dist/cli/commands/gateway/index.js.map +1 -0
- package/dist/cli/commands/gateway/key.d.ts +3 -0
- package/dist/cli/commands/gateway/key.d.ts.map +1 -0
- package/dist/cli/commands/gateway/key.js +240 -0
- package/dist/cli/commands/gateway/key.js.map +1 -0
- package/dist/cli/commands/gateway/shared.d.ts +29 -0
- package/dist/cli/commands/gateway/shared.d.ts.map +1 -0
- package/dist/cli/commands/gateway/shared.js +90 -0
- package/dist/cli/commands/gateway/shared.js.map +1 -0
- package/dist/cli/commands/tunnel/start.d.ts.map +1 -1
- package/dist/cli/commands/tunnel/start.js +25 -14
- package/dist/cli/commands/tunnel/start.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/accounting.d.ts +45 -0
- package/dist/gateway/accounting.d.ts.map +1 -0
- package/dist/gateway/accounting.js +94 -0
- package/dist/gateway/accounting.js.map +1 -0
- package/dist/gateway/cdp-auth.d.ts +12 -0
- package/dist/gateway/cdp-auth.d.ts.map +1 -0
- package/dist/gateway/cdp-auth.js +53 -0
- package/dist/gateway/cdp-auth.js.map +1 -0
- package/dist/gateway/cdp-auth.test.d.ts +2 -0
- package/dist/gateway/cdp-auth.test.d.ts.map +1 -0
- package/dist/gateway/cdp-auth.test.js +96 -0
- package/dist/gateway/cdp-auth.test.js.map +1 -0
- package/dist/gateway/gateway.test.d.ts.map +1 -0
- package/dist/gateway/gateway.test.js +709 -0
- package/dist/gateway/gateway.test.js.map +1 -0
- package/dist/gateway/keys.d.ts +13 -0
- package/dist/gateway/keys.d.ts.map +1 -0
- package/dist/gateway/keys.js +24 -0
- package/dist/gateway/keys.js.map +1 -0
- package/dist/gateway/limits.d.ts +25 -0
- package/dist/gateway/limits.d.ts.map +1 -0
- package/dist/gateway/limits.js +45 -0
- package/dist/gateway/limits.js.map +1 -0
- package/dist/gateway/money.d.ts +9 -0
- package/dist/gateway/money.d.ts.map +1 -0
- package/dist/gateway/money.js +37 -0
- package/dist/gateway/money.js.map +1 -0
- package/dist/gateway/runtime.d.ts +38 -0
- package/dist/gateway/runtime.d.ts.map +1 -0
- package/dist/gateway/runtime.js +144 -0
- package/dist/gateway/runtime.js.map +1 -0
- package/dist/gateway/server.d.ts +49 -0
- package/dist/gateway/server.d.ts.map +1 -0
- package/dist/gateway/server.js +460 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/gateway/spend-feed.d.ts +32 -0
- package/dist/gateway/spend-feed.d.ts.map +1 -0
- package/dist/gateway/spend-feed.js +86 -0
- package/dist/gateway/spend-feed.js.map +1 -0
- package/dist/gateway/store.d.ts +114 -0
- package/dist/gateway/store.d.ts.map +1 -0
- package/dist/gateway/store.js +253 -0
- package/dist/gateway/store.js.map +1 -0
- package/dist/gateway/x402.d.ts +95 -0
- package/dist/gateway/x402.d.ts.map +1 -0
- package/dist/gateway/x402.js +120 -0
- package/dist/gateway/x402.js.map +1 -0
- package/dist/proxy/buyer-proxy.d.ts +13 -0
- package/dist/proxy/buyer-proxy.d.ts.map +1 -1
- package/dist/proxy/buyer-proxy.js +99 -11
- package/dist/proxy/buyer-proxy.js.map +1 -1
- package/dist/proxy/request-utils.d.ts +3 -0
- package/dist/proxy/request-utils.d.ts.map +1 -1
- package/dist/proxy/request-utils.js +3 -0
- package/dist/proxy/request-utils.js.map +1 -1
- package/dist/proxy/spend-attribution.d.ts +63 -0
- package/dist/proxy/spend-attribution.d.ts.map +1 -0
- package/dist/proxy/spend-attribution.js +97 -0
- package/dist/proxy/spend-attribution.js.map +1 -0
- package/package.json +8 -6
- package/dist/tunnel/gateway.d.ts +0 -16
- package/dist/tunnel/gateway.d.ts.map +0 -1
- package/dist/tunnel/gateway.js +0 -146
- package/dist/tunnel/gateway.js.map +0 -1
- package/dist/tunnel/gateway.test.d.ts.map +0 -1
- package/dist/tunnel/gateway.test.js +0 -89
- package/dist/tunnel/gateway.test.js.map +0 -1
- /package/dist/{tunnel → gateway}/gateway.test.d.ts +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type AntseedNode, type Identity } from '@antseed/node';
|
|
2
|
+
import { type StoredBuyerIdentity } from './store.js';
|
|
3
|
+
type IdentityNode = Pick<AntseedNode, 'hasBuyerIdentity' | 'addBuyerIdentity'>;
|
|
4
|
+
/**
|
|
5
|
+
* Loads stored buyer identities into a running buyer node. Identities are
|
|
6
|
+
* loaded at startup and on first use, so one created while the buyer runs
|
|
7
|
+
* works without a restart.
|
|
8
|
+
*/
|
|
9
|
+
export declare class BuyerIdentityLoader {
|
|
10
|
+
private readonly _node;
|
|
11
|
+
private readonly _dataDir;
|
|
12
|
+
/** Called once per identity after it joins the node (e.g. to watch its wallet for deposits). */
|
|
13
|
+
private readonly _onLoaded?;
|
|
14
|
+
private readonly _pending;
|
|
15
|
+
constructor(_node: IdentityNode, _dataDir: string,
|
|
16
|
+
/** Called once per identity after it joins the node (e.g. to watch its wallet for deposits). */
|
|
17
|
+
_onLoaded?: ((name: string, identity: Identity) => void) | undefined);
|
|
18
|
+
/** True when the node can pay as `name`, loading it from disk if needed. */
|
|
19
|
+
ensure(name: string): Promise<boolean>;
|
|
20
|
+
/** Loads every stored identity; `failed` lists those whose key could not be read, with the reason. */
|
|
21
|
+
loadAll(): Promise<{
|
|
22
|
+
loaded: StoredBuyerIdentity[];
|
|
23
|
+
failed: StoredBuyerIdentity[];
|
|
24
|
+
}>;
|
|
25
|
+
private _load;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/buyer-identities/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AACvF,OAAO,EAA0C,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAE7F,KAAK,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,kBAAkB,GAAG,kBAAkB,CAAC,CAAA;AAE9E;;;;GAIG;AACH,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,gGAAgG;IAChG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAN7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;gBAG5C,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,MAAM;IACjC,gGAAgG;IAC/E,SAAS,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,aAAA;IAGzE,4EAA4E;IAC5E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUtC,sGAAsG;IAChG,OAAO,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QAAC,MAAM,EAAE,mBAAmB,EAAE,CAAA;KAAE,CAAC;YAmB5E,KAAK;CAOpB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { DEFAULT_BUYER_IDENTITY } from '@antseed/node';
|
|
2
|
+
import { listBuyerIdentities, loadBuyerIdentity } from './store.js';
|
|
3
|
+
/**
|
|
4
|
+
* Loads stored buyer identities into a running buyer node. Identities are
|
|
5
|
+
* loaded at startup and on first use, so one created while the buyer runs
|
|
6
|
+
* works without a restart.
|
|
7
|
+
*/
|
|
8
|
+
export class BuyerIdentityLoader {
|
|
9
|
+
_node;
|
|
10
|
+
_dataDir;
|
|
11
|
+
_onLoaded;
|
|
12
|
+
_pending = new Map();
|
|
13
|
+
constructor(_node, _dataDir,
|
|
14
|
+
/** Called once per identity after it joins the node (e.g. to watch its wallet for deposits). */
|
|
15
|
+
_onLoaded) {
|
|
16
|
+
this._node = _node;
|
|
17
|
+
this._dataDir = _dataDir;
|
|
18
|
+
this._onLoaded = _onLoaded;
|
|
19
|
+
}
|
|
20
|
+
/** True when the node can pay as `name`, loading it from disk if needed. */
|
|
21
|
+
ensure(name) {
|
|
22
|
+
if (name === DEFAULT_BUYER_IDENTITY || this._node.hasBuyerIdentity(name))
|
|
23
|
+
return Promise.resolve(true);
|
|
24
|
+
let pending = this._pending.get(name);
|
|
25
|
+
if (!pending) {
|
|
26
|
+
pending = this._load(name).finally(() => this._pending.delete(name));
|
|
27
|
+
this._pending.set(name, pending);
|
|
28
|
+
}
|
|
29
|
+
return pending;
|
|
30
|
+
}
|
|
31
|
+
/** Loads every stored identity; `failed` lists those whose key could not be read, with the reason. */
|
|
32
|
+
async loadAll() {
|
|
33
|
+
const stored = await listBuyerIdentities(this._dataDir);
|
|
34
|
+
const loaded = [];
|
|
35
|
+
const failed = [];
|
|
36
|
+
for (const entry of stored) {
|
|
37
|
+
if (entry.error) {
|
|
38
|
+
failed.push(entry);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const error = await this.ensure(entry.name).then((ok) => (ok ? null : 'no longer stored'), (err) => (err instanceof Error ? err.message : String(err)));
|
|
42
|
+
if (error)
|
|
43
|
+
failed.push({ ...entry, error });
|
|
44
|
+
else
|
|
45
|
+
loaded.push(entry);
|
|
46
|
+
}
|
|
47
|
+
return { loaded, failed };
|
|
48
|
+
}
|
|
49
|
+
async _load(name) {
|
|
50
|
+
const identity = await loadBuyerIdentity(this._dataDir, name);
|
|
51
|
+
if (!identity)
|
|
52
|
+
return false;
|
|
53
|
+
await this._node.addBuyerIdentity(name, identity);
|
|
54
|
+
this._onLoaded?.(name, identity);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/buyer-identities/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAmC,MAAM,eAAe,CAAA;AACvF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAA4B,MAAM,YAAY,CAAA;AAI7F;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAIX;IACA;IAEA;IANF,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAA;IAE/D,YACmB,KAAmB,EACnB,QAAgB;IACjC,gGAAgG;IAC/E,SAAsD;QAHtD,UAAK,GAAL,KAAK,CAAc;QACnB,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,cAAS,GAAT,SAAS,CAA6C;IACtE,CAAC;IAEJ,4EAA4E;IAC5E,MAAM,CAAC,IAAY;QACjB,IAAI,IAAI,KAAK,sBAAsB,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACtG,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;YACpE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,sGAAsG;IACtG,KAAK,CAAC,OAAO;QACX,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACvD,MAAM,MAAM,GAA0B,EAAE,CAAA;QACxC,MAAM,MAAM,GAA0B,EAAE,CAAA;QACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAClB,SAAQ;YACV,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAC9C,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,EACxC,CAAC,GAAY,EAAE,EAAE,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACrE,CAAA;YACD,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;;gBACtC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACzB,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;IAC3B,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,IAAY;QAC9B,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC7D,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC3B,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACjD,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Identity } from '@antseed/node';
|
|
2
|
+
export interface StoredBuyerIdentity {
|
|
3
|
+
name: string;
|
|
4
|
+
/** Null when the key cannot be read; `error` says why. */
|
|
5
|
+
address: string | null;
|
|
6
|
+
dir: string;
|
|
7
|
+
/** Where the key comes from when it is not stored in the data dir. */
|
|
8
|
+
keyFrom?: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function buyerIdentitiesDir(dataDir: string): string;
|
|
12
|
+
export declare function buyerIdentityDir(dataDir: string, name: string): string;
|
|
13
|
+
export declare function assertBuyerIdentityName(name: string): void;
|
|
14
|
+
/** Validates a `--key-from` value: `env:<VAR>` or `file:<absolute path>`. */
|
|
15
|
+
export declare function parseKeySource(spec: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Without `keyFrom`, a new key is generated and stored in the data dir.
|
|
18
|
+
* Generated directly rather than through loadOrCreateIdentity, which would
|
|
19
|
+
* adopt an ANTSEED_IDENTITY_HEX inherited from a parent process and give the
|
|
20
|
+
* new identity the default wallet. With `keyFrom`, only the reference is
|
|
21
|
+
* stored and the key is read from it on every load.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createBuyerIdentity(dataDir: string, name: string, keyFrom?: string): Promise<StoredBuyerIdentity>;
|
|
24
|
+
/** True when an identity with this name is stored, without reading its key. */
|
|
25
|
+
export declare function buyerIdentityExists(dataDir: string, name: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* The identity's wallet, or null when no identity has that name. Throws when
|
|
28
|
+
* it exists but its key cannot be read, rather than falling back to anything.
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadBuyerIdentity(dataDir: string, name: string): Promise<Identity | null>;
|
|
31
|
+
export declare function listBuyerIdentities(dataDir: string): Promise<StoredBuyerIdentity[]>;
|
|
32
|
+
/** The default wallet's address, or why the CLI cannot read it. */
|
|
33
|
+
export declare function readDefaultWallet(dataDir: string): Promise<{
|
|
34
|
+
address: string | null;
|
|
35
|
+
note: string;
|
|
36
|
+
}>;
|
|
37
|
+
/** Wallet address of any identity, default included; null when unknown or unreadable. */
|
|
38
|
+
export declare function buyerIdentityAddress(dataDir: string, name: string): Promise<string | null>;
|
|
39
|
+
/** Move an identity aside; its key is kept because the wallet may still hold funds. */
|
|
40
|
+
export declare function archiveBuyerIdentity(dataDir: string, name: string): Promise<string>;
|
|
41
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/buyer-identities/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,eAAe,CAAA;AAgBtB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAK1D;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnD;AAqBD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAevH;AAED,+EAA+E;AAC/E,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGzF;AAWD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAY/F;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAoBzF;AAED,mEAAmE;AACnE,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ1G;AAED,yFAAyF;AACzF,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGhG;AAED,uFAAuF;AACvF,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASzF"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { access, mkdir, readdir, readFile, rename, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { isAbsolute, join } from 'node:path';
|
|
4
|
+
import { DEFAULT_BUYER_IDENTITY, FileIdentityStore, identityFromPrivateKeyHex, isValidBuyerIdentityName, } from '@antseed/node';
|
|
5
|
+
/**
|
|
6
|
+
* Extra buyer wallets live next to the default identity, one directory each:
|
|
7
|
+
* <dataDir>/buyer-identities/<name>/identity.key (the private key), or
|
|
8
|
+
* <dataDir>/buyer-identities/<name>/identity.json ({"keyFrom": "env:VAR" | "file:/path"})
|
|
9
|
+
* The second form keeps the key out of the data dir: it is read at load time
|
|
10
|
+
* from an env var or a file a secret manager provides.
|
|
11
|
+
* A running buyer pays as any of them when a request names it.
|
|
12
|
+
*/
|
|
13
|
+
const IDENTITIES_DIR = 'buyer-identities';
|
|
14
|
+
const ARCHIVE_DIR = '.archived';
|
|
15
|
+
const KEY_FILE = 'identity.key';
|
|
16
|
+
const KEY_SOURCE_FILE = 'identity.json';
|
|
17
|
+
const ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
18
|
+
export function buyerIdentitiesDir(dataDir) {
|
|
19
|
+
return join(dataDir, IDENTITIES_DIR);
|
|
20
|
+
}
|
|
21
|
+
export function buyerIdentityDir(dataDir, name) {
|
|
22
|
+
return join(buyerIdentitiesDir(dataDir), name);
|
|
23
|
+
}
|
|
24
|
+
export function assertBuyerIdentityName(name) {
|
|
25
|
+
if (name === DEFAULT_BUYER_IDENTITY)
|
|
26
|
+
throw new Error(`"${DEFAULT_BUYER_IDENTITY}" is the identity in your data dir and always exists.`);
|
|
27
|
+
if (!isValidBuyerIdentityName(name)) {
|
|
28
|
+
throw new Error('Identity names use lowercase letters, digits and dashes (max 32 characters).');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Validates a `--key-from` value: `env:<VAR>` or `file:<absolute path>`. */
|
|
32
|
+
export function parseKeySource(spec) {
|
|
33
|
+
const [kind, ...rest] = spec.split(':');
|
|
34
|
+
const target = rest.join(':');
|
|
35
|
+
if (kind === 'env' && ENV_NAME_PATTERN.test(target))
|
|
36
|
+
return spec;
|
|
37
|
+
if (kind === 'file' && isAbsolute(target))
|
|
38
|
+
return spec;
|
|
39
|
+
throw new Error('--key-from takes env:<VAR> or file:<absolute path>.');
|
|
40
|
+
}
|
|
41
|
+
async function readKeyFromSource(keyFrom) {
|
|
42
|
+
const [kind, ...rest] = keyFrom.split(':');
|
|
43
|
+
const target = rest.join(':');
|
|
44
|
+
let raw;
|
|
45
|
+
if (kind === 'env') {
|
|
46
|
+
raw = process.env[target];
|
|
47
|
+
if (!raw)
|
|
48
|
+
throw new Error(`env var ${target} is not set`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
raw = await readFile(target, 'utf8').catch(() => { throw new Error(`cannot read ${target}`); });
|
|
52
|
+
}
|
|
53
|
+
const hex = raw.trim().replace(/^0x/, '');
|
|
54
|
+
if (!/^[0-9a-fA-F]{64}$/.test(hex))
|
|
55
|
+
throw new Error(`${keyFrom} does not hold a 32-byte hex private key`);
|
|
56
|
+
return hex.toLowerCase();
|
|
57
|
+
}
|
|
58
|
+
async function exists(path) {
|
|
59
|
+
return access(path).then(() => true, () => false);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Without `keyFrom`, a new key is generated and stored in the data dir.
|
|
63
|
+
* Generated directly rather than through loadOrCreateIdentity, which would
|
|
64
|
+
* adopt an ANTSEED_IDENTITY_HEX inherited from a parent process and give the
|
|
65
|
+
* new identity the default wallet. With `keyFrom`, only the reference is
|
|
66
|
+
* stored and the key is read from it on every load.
|
|
67
|
+
*/
|
|
68
|
+
export async function createBuyerIdentity(dataDir, name, keyFrom) {
|
|
69
|
+
assertBuyerIdentityName(name);
|
|
70
|
+
const dir = buyerIdentityDir(dataDir, name);
|
|
71
|
+
if (await buyerIdentityExists(dataDir, name)) {
|
|
72
|
+
throw new Error(`Buyer identity "${name}" already exists.`);
|
|
73
|
+
}
|
|
74
|
+
if (keyFrom) {
|
|
75
|
+
const hex = await readKeyFromSource(parseKeySource(keyFrom));
|
|
76
|
+
await mkdir(dir, { recursive: true });
|
|
77
|
+
await writeFile(join(dir, KEY_SOURCE_FILE), `${JSON.stringify({ keyFrom }, null, 2)}\n`, { mode: 0o600 });
|
|
78
|
+
return { name, address: identityFromPrivateKeyHex(hex).wallet.address, dir, keyFrom };
|
|
79
|
+
}
|
|
80
|
+
const hex = randomBytes(32).toString('hex');
|
|
81
|
+
await new FileIdentityStore(dir).save(hex);
|
|
82
|
+
return { name, address: identityFromPrivateKeyHex(hex).wallet.address, dir };
|
|
83
|
+
}
|
|
84
|
+
/** True when an identity with this name is stored, without reading its key. */
|
|
85
|
+
export async function buyerIdentityExists(dataDir, name) {
|
|
86
|
+
const dir = buyerIdentityDir(dataDir, name);
|
|
87
|
+
return await exists(join(dir, KEY_FILE)) || await exists(join(dir, KEY_SOURCE_FILE));
|
|
88
|
+
}
|
|
89
|
+
/** Where an identity's key comes from, or null when it is stored in the data dir. */
|
|
90
|
+
async function readKeySourceRef(dir) {
|
|
91
|
+
const raw = await readFile(join(dir, KEY_SOURCE_FILE), 'utf8').catch(() => null);
|
|
92
|
+
if (raw === null)
|
|
93
|
+
return null;
|
|
94
|
+
const keyFrom = JSON.parse(raw).keyFrom;
|
|
95
|
+
if (typeof keyFrom !== 'string')
|
|
96
|
+
throw new Error(`${KEY_SOURCE_FILE} has no keyFrom`);
|
|
97
|
+
return parseKeySource(keyFrom);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The identity's wallet, or null when no identity has that name. Throws when
|
|
101
|
+
* it exists but its key cannot be read, rather than falling back to anything.
|
|
102
|
+
*/
|
|
103
|
+
export async function loadBuyerIdentity(dataDir, name) {
|
|
104
|
+
if (!isValidBuyerIdentityName(name) || name === DEFAULT_BUYER_IDENTITY)
|
|
105
|
+
return null;
|
|
106
|
+
const dir = buyerIdentityDir(dataDir, name);
|
|
107
|
+
const keyFrom = await readKeySourceRef(dir);
|
|
108
|
+
if (keyFrom) {
|
|
109
|
+
if (await exists(join(dir, KEY_FILE))) {
|
|
110
|
+
throw new Error(`Buyer identity "${name}" has both ${KEY_FILE} and ${KEY_SOURCE_FILE}; remove the one you did not mean to use`);
|
|
111
|
+
}
|
|
112
|
+
return identityFromPrivateKeyHex(await readKeyFromSource(keyFrom));
|
|
113
|
+
}
|
|
114
|
+
const hex = await new FileIdentityStore(dir).load();
|
|
115
|
+
return hex && hex.length === 64 ? identityFromPrivateKeyHex(hex) : null;
|
|
116
|
+
}
|
|
117
|
+
export async function listBuyerIdentities(dataDir) {
|
|
118
|
+
let names;
|
|
119
|
+
try {
|
|
120
|
+
names = await readdir(buyerIdentitiesDir(dataDir));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
const identities = [];
|
|
126
|
+
for (const name of names.sort()) {
|
|
127
|
+
if (!isValidBuyerIdentityName(name) || name === DEFAULT_BUYER_IDENTITY)
|
|
128
|
+
continue;
|
|
129
|
+
const dir = buyerIdentityDir(dataDir, name);
|
|
130
|
+
const keyFrom = await readKeySourceRef(dir).catch(() => undefined);
|
|
131
|
+
try {
|
|
132
|
+
const identity = await loadBuyerIdentity(dataDir, name);
|
|
133
|
+
if (identity)
|
|
134
|
+
identities.push({ name, address: identity.wallet.address, dir, ...(keyFrom ? { keyFrom } : {}) });
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
identities.push({ name, address: null, dir, ...(keyFrom ? { keyFrom } : {}), error: err instanceof Error ? err.message : String(err) });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return identities;
|
|
141
|
+
}
|
|
142
|
+
/** The default wallet's address, or why the CLI cannot read it. */
|
|
143
|
+
export async function readDefaultWallet(dataDir) {
|
|
144
|
+
try {
|
|
145
|
+
const hex = await new FileIdentityStore(dataDir).load();
|
|
146
|
+
if (hex && hex.length === 64)
|
|
147
|
+
return { address: identityFromPrivateKeyHex(hex).wallet.address, note: '' };
|
|
148
|
+
return { address: null, note: 'created on first buyer start' };
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return { address: null, note: 'encrypted by the AI VPN' };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Wallet address of any identity, default included; null when unknown or unreadable. */
|
|
155
|
+
export async function buyerIdentityAddress(dataDir, name) {
|
|
156
|
+
if (name === DEFAULT_BUYER_IDENTITY)
|
|
157
|
+
return (await readDefaultWallet(dataDir)).address;
|
|
158
|
+
return (await loadBuyerIdentity(dataDir, name).catch(() => null))?.wallet.address ?? null;
|
|
159
|
+
}
|
|
160
|
+
/** Move an identity aside; its key is kept because the wallet may still hold funds. */
|
|
161
|
+
export async function archiveBuyerIdentity(dataDir, name) {
|
|
162
|
+
assertBuyerIdentityName(name);
|
|
163
|
+
const dir = buyerIdentityDir(dataDir, name);
|
|
164
|
+
await stat(dir).catch(() => { throw new Error(`Unknown buyer identity "${name}".`); });
|
|
165
|
+
const archiveRoot = join(buyerIdentitiesDir(dataDir), ARCHIVE_DIR);
|
|
166
|
+
await mkdir(archiveRoot, { recursive: true });
|
|
167
|
+
const target = join(archiveRoot, `${name}-${Date.now()}`);
|
|
168
|
+
await rename(dir, target);
|
|
169
|
+
return target;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/buyer-identities/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../src/buyer-identities/store.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { test } from 'node:test';
|
|
6
|
+
import { identityFromPrivateKeyHex } from '@antseed/node';
|
|
7
|
+
import { BuyerIdentityLoader } from './loader.js';
|
|
8
|
+
import { randomBytes } from 'node:crypto';
|
|
9
|
+
import { archiveBuyerIdentity, buyerIdentityExists, createBuyerIdentity, listBuyerIdentities, loadBuyerIdentity, parseKeySource } from './store.js';
|
|
10
|
+
function randomWallet() {
|
|
11
|
+
const hex = randomBytes(32).toString('hex');
|
|
12
|
+
return { privateKey: `0x${hex}`, address: identityFromPrivateKeyHex(hex).wallet.address };
|
|
13
|
+
}
|
|
14
|
+
function tempDataDir() {
|
|
15
|
+
const dataDir = mkdtempSync(join(tmpdir(), 'antseed-identities-'));
|
|
16
|
+
return { dataDir, cleanup: () => rmSync(dataDir, { recursive: true, force: true }) };
|
|
17
|
+
}
|
|
18
|
+
test('buyer identities are created, listed, loaded and archived by name', async () => {
|
|
19
|
+
const { dataDir, cleanup } = tempDataDir();
|
|
20
|
+
try {
|
|
21
|
+
const team = await createBuyerIdentity(dataDir, 'team-a');
|
|
22
|
+
const ops = await createBuyerIdentity(dataDir, 'ops');
|
|
23
|
+
assert.notEqual(team.address, ops.address);
|
|
24
|
+
await assert.rejects(createBuyerIdentity(dataDir, 'team-a'), /already exists/);
|
|
25
|
+
await assert.rejects(createBuyerIdentity(dataDir, 'default'), /always exists/);
|
|
26
|
+
await assert.rejects(createBuyerIdentity(dataDir, 'Bad Name'), /lowercase/);
|
|
27
|
+
assert.deepEqual((await listBuyerIdentities(dataDir)).map((entry) => entry.name), ['ops', 'team-a']);
|
|
28
|
+
assert.equal((await loadBuyerIdentity(dataDir, 'team-a'))?.wallet.address, team.address);
|
|
29
|
+
assert.equal(await loadBuyerIdentity(dataDir, 'missing'), null);
|
|
30
|
+
const archived = await archiveBuyerIdentity(dataDir, 'team-a');
|
|
31
|
+
assert.ok(existsSync(join(archived, 'identity.key')), 'archiving keeps the key');
|
|
32
|
+
assert.deepEqual((await listBuyerIdentities(dataDir)).map((entry) => entry.name), ['ops']);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
cleanup();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
test('the loader adds stored identities to the node once, on demand', async () => {
|
|
39
|
+
const { dataDir, cleanup } = tempDataDir();
|
|
40
|
+
try {
|
|
41
|
+
await createBuyerIdentity(dataDir, 'team-a');
|
|
42
|
+
const added = [];
|
|
43
|
+
const node = {
|
|
44
|
+
hasBuyerIdentity: (name) => added.includes(name),
|
|
45
|
+
addBuyerIdentity: async (name, identity) => {
|
|
46
|
+
added.push(name);
|
|
47
|
+
return { name, address: identity.wallet.address };
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
const loaded = [];
|
|
51
|
+
const loader = new BuyerIdentityLoader(node, dataDir, (name) => loaded.push(name));
|
|
52
|
+
assert.equal(await loader.ensure('default'), true);
|
|
53
|
+
const [first, second] = await Promise.all([loader.ensure('team-a'), loader.ensure('team-a')]);
|
|
54
|
+
assert.equal(first && second, true);
|
|
55
|
+
assert.equal(await loader.ensure('missing'), false);
|
|
56
|
+
assert.deepEqual(added, ['team-a']);
|
|
57
|
+
assert.deepEqual(loaded, ['team-a']);
|
|
58
|
+
await createBuyerIdentity(dataDir, 'late');
|
|
59
|
+
assert.deepEqual((await loader.loadAll()).loaded.map((entry) => entry.name), ['late', 'team-a']);
|
|
60
|
+
assert.deepEqual(added, ['team-a', 'late']);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
cleanup();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
test('identities can read their key from an env var or a secret file instead of the data dir', async () => {
|
|
67
|
+
const { dataDir, cleanup } = tempDataDir();
|
|
68
|
+
const envWallet = randomWallet();
|
|
69
|
+
const fileWallet = randomWallet();
|
|
70
|
+
const secretFile = join(dataDir, 'mounted-secret');
|
|
71
|
+
writeFileSync(secretFile, `${fileWallet.privateKey}\n`);
|
|
72
|
+
process.env['TEST_TEAM_A_KEY'] = envWallet.privateKey.slice(2);
|
|
73
|
+
try {
|
|
74
|
+
assert.throws(() => parseKeySource('vault:team-a'), /env:<VAR> or file:<absolute path>/);
|
|
75
|
+
assert.throws(() => parseKeySource('file:relative/path'), /absolute/);
|
|
76
|
+
await assert.rejects(createBuyerIdentity(dataDir, 'unset', 'env:TEST_UNSET_KEY'), /not set/);
|
|
77
|
+
assert.equal(await buyerIdentityExists(dataDir, 'unset'), false);
|
|
78
|
+
const fromEnv = await createBuyerIdentity(dataDir, 'team-a', 'env:TEST_TEAM_A_KEY');
|
|
79
|
+
const fromFile = await createBuyerIdentity(dataDir, 'team-b', `file:${secretFile}`);
|
|
80
|
+
assert.equal(fromEnv.address, envWallet.address);
|
|
81
|
+
assert.equal(fromFile.address, fileWallet.address);
|
|
82
|
+
assert.ok(!existsSync(join(fromEnv.dir, 'identity.key')), 'no key is written to the data dir');
|
|
83
|
+
assert.ok(!readFileSync(join(fromEnv.dir, 'identity.json'), 'utf8').includes(envWallet.privateKey.slice(2)));
|
|
84
|
+
assert.equal((await loadBuyerIdentity(dataDir, 'team-b'))?.wallet.address, fileWallet.address);
|
|
85
|
+
delete process.env['TEST_TEAM_A_KEY'];
|
|
86
|
+
await assert.rejects(loadBuyerIdentity(dataDir, 'team-a'), /TEST_TEAM_A_KEY is not set/);
|
|
87
|
+
const listed = await listBuyerIdentities(dataDir);
|
|
88
|
+
assert.deepEqual(listed.map((entry) => [entry.name, entry.address, entry.keyFrom]), [
|
|
89
|
+
['team-a', null, 'env:TEST_TEAM_A_KEY'],
|
|
90
|
+
['team-b', fileWallet.address, `file:${secretFile}`],
|
|
91
|
+
]);
|
|
92
|
+
assert.match(listed[0].error ?? '', /not set/);
|
|
93
|
+
writeFileSync(join(fromFile.dir, 'identity.key'), randomWallet().privateKey.slice(2));
|
|
94
|
+
await assert.rejects(loadBuyerIdentity(dataDir, 'team-b'), /both identity.key and identity.json/);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
delete process.env['TEST_TEAM_A_KEY'];
|
|
98
|
+
cleanup();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
test('the loader reports identities whose key cannot be read', async () => {
|
|
102
|
+
const { dataDir, cleanup } = tempDataDir();
|
|
103
|
+
process.env['TEST_LOADER_KEY'] = randomWallet().privateKey;
|
|
104
|
+
try {
|
|
105
|
+
await createBuyerIdentity(dataDir, 'ok');
|
|
106
|
+
await createBuyerIdentity(dataDir, 'external', 'env:TEST_LOADER_KEY');
|
|
107
|
+
delete process.env['TEST_LOADER_KEY'];
|
|
108
|
+
const node = {
|
|
109
|
+
hasBuyerIdentity: () => false,
|
|
110
|
+
addBuyerIdentity: async (name, identity) => ({ name, address: identity.wallet.address }),
|
|
111
|
+
};
|
|
112
|
+
const { loaded, failed } = await new BuyerIdentityLoader(node, dataDir).loadAll();
|
|
113
|
+
assert.deepEqual(loaded.map((entry) => entry.name), ['ok']);
|
|
114
|
+
assert.deepEqual(failed.map((entry) => entry.name), ['external']);
|
|
115
|
+
assert.match(failed[0].error ?? '', /TEST_LOADER_KEY is not set/);
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
delete process.env['TEST_LOADER_KEY'];
|
|
119
|
+
cleanup();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../src/buyer-identities/store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/buyer/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAA;AAY9D,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAwGrE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { InvalidArgumentError } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import { DEFAULT_BUYER_IDENTITY, DepositsClient, resolveChainConfig } from '@antseed/node';
|
|
5
|
+
import { getGlobalOptions } from '../types.js';
|
|
6
|
+
import { loadConfig } from '../../../config/loader.js';
|
|
7
|
+
import { archiveBuyerIdentity, createBuyerIdentity, listBuyerIdentities, parseKeySource, readDefaultWallet } from '../../../buyer-identities/store.js';
|
|
8
|
+
function formatUsdc(baseUnits) {
|
|
9
|
+
return (Number(baseUnits) / 1_000_000).toFixed(2);
|
|
10
|
+
}
|
|
11
|
+
export function registerBuyerIdentityCommands(buyerCmd) {
|
|
12
|
+
const identity = buyerCmd
|
|
13
|
+
.command('identity')
|
|
14
|
+
.description('Extra buyer wallets one running buyer can pay as (select per request with x-antseed-buyer-identity)');
|
|
15
|
+
identity.command('create')
|
|
16
|
+
.description('Create a buyer identity with its own wallet')
|
|
17
|
+
.argument('<name>', 'identity name (lowercase letters, digits, dashes)')
|
|
18
|
+
.option('--key-from <source>', 'read an existing private key from env:<VAR> or file:<absolute path> on every load, instead of storing one in the data dir', (value) => {
|
|
19
|
+
try {
|
|
20
|
+
return parseKeySource(value);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
throw new InvalidArgumentError(err.message);
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
.action(async (name, options) => {
|
|
27
|
+
const { dataDir } = getGlobalOptions(buyerCmd);
|
|
28
|
+
const created = await createBuyerIdentity(dataDir, name, options.keyFrom);
|
|
29
|
+
console.log(chalk.green(`Created buyer identity ${created.name}`));
|
|
30
|
+
console.log(`Wallet: ${created.address}`);
|
|
31
|
+
if (created.keyFrom) {
|
|
32
|
+
console.log(chalk.dim(`Key: read from ${created.keyFrom}; it is not stored in the data dir. The buyer must be started with it available.`));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log(chalk.dim(`Key: ${created.dir}/identity.key — back it up; the wallet holds this identity's credits.`));
|
|
36
|
+
}
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log('Fund it by sending USDC on Base to the wallet. A running buyer deposits it into the');
|
|
39
|
+
console.log("identity's credits automatically.");
|
|
40
|
+
if (!created.keyFrom) {
|
|
41
|
+
console.log('To show the address as a QR code:');
|
|
42
|
+
console.log(chalk.dim(` antseed --data-dir ${created.dir} buyer deposit --no-watch`));
|
|
43
|
+
}
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(`Use it by sending ${chalk.bold(`x-antseed-buyer-identity: ${created.name}`)} with requests to the buyer.`);
|
|
46
|
+
});
|
|
47
|
+
identity.command('list')
|
|
48
|
+
.description('List buyer identities')
|
|
49
|
+
.option('--balances', 'read each wallet\'s deposits balance from the chain', false)
|
|
50
|
+
.option('--json', 'print machine-readable JSON', false)
|
|
51
|
+
.action(async (options) => {
|
|
52
|
+
const globalOpts = getGlobalOptions(buyerCmd);
|
|
53
|
+
const stored = await listBuyerIdentities(globalOpts.dataDir);
|
|
54
|
+
const defaultWallet = await readDefaultWallet(globalOpts.dataDir);
|
|
55
|
+
const rows = [
|
|
56
|
+
{ name: DEFAULT_BUYER_IDENTITY, address: defaultWallet.address },
|
|
57
|
+
...stored.map((entry) => ({
|
|
58
|
+
name: entry.name,
|
|
59
|
+
address: entry.address,
|
|
60
|
+
...(entry.keyFrom ? { keyFrom: entry.keyFrom } : {}),
|
|
61
|
+
...(entry.error ? { error: entry.error } : {}),
|
|
62
|
+
})),
|
|
63
|
+
];
|
|
64
|
+
if (options.balances) {
|
|
65
|
+
const config = await loadConfig(globalOpts.config);
|
|
66
|
+
const crypto = config.payments?.crypto;
|
|
67
|
+
const chainConfig = resolveChainConfig({
|
|
68
|
+
chainId: crypto?.chainId,
|
|
69
|
+
rpcUrl: crypto?.rpcUrl,
|
|
70
|
+
depositsContractAddress: crypto?.depositsContractAddress,
|
|
71
|
+
usdcContractAddress: crypto?.usdcContractAddress,
|
|
72
|
+
});
|
|
73
|
+
const deposits = new DepositsClient({
|
|
74
|
+
rpcUrl: chainConfig.rpcUrl,
|
|
75
|
+
...(chainConfig.fallbackRpcUrls ? { fallbackRpcUrls: chainConfig.fallbackRpcUrls } : {}),
|
|
76
|
+
contractAddress: chainConfig.depositsContractAddress,
|
|
77
|
+
usdcAddress: chainConfig.usdcContractAddress,
|
|
78
|
+
evmChainId: chainConfig.evmChainId,
|
|
79
|
+
});
|
|
80
|
+
await Promise.all(rows.map(async (row) => {
|
|
81
|
+
if (!row.address)
|
|
82
|
+
return;
|
|
83
|
+
const account = await deposits.getBuyerBalance(row.address).catch(() => null);
|
|
84
|
+
if (!account)
|
|
85
|
+
return;
|
|
86
|
+
row.available = formatUsdc(account.available);
|
|
87
|
+
row.reserved = formatUsdc(account.reserved);
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
if (options.json) {
|
|
91
|
+
console.log(JSON.stringify(rows));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const table = new Table({ head: ['Name', 'Wallet', 'Key', ...(options.balances ? ['Available', 'Reserved'] : [])] });
|
|
95
|
+
for (const row of rows) {
|
|
96
|
+
table.push([
|
|
97
|
+
row.name,
|
|
98
|
+
row.address ?? (row.error ? chalk.yellow(row.error) : chalk.dim(defaultWallet.note)),
|
|
99
|
+
row.keyFrom ?? 'data dir',
|
|
100
|
+
...(options.balances ? [row.available ?? '-', row.reserved ?? '-'] : []),
|
|
101
|
+
]);
|
|
102
|
+
}
|
|
103
|
+
console.log(table.toString());
|
|
104
|
+
});
|
|
105
|
+
identity.command('remove')
|
|
106
|
+
.description('Stop using a buyer identity; its key is archived, not deleted')
|
|
107
|
+
.argument('<name>', 'identity name')
|
|
108
|
+
.action(async (name) => {
|
|
109
|
+
const { dataDir } = getGlobalOptions(buyerCmd);
|
|
110
|
+
const archived = await archiveBuyerIdentity(dataDir, name);
|
|
111
|
+
console.log(`Removed buyer identity ${name}. Its key was moved to ${archived}.`);
|
|
112
|
+
console.log(chalk.dim('A running buyer keeps it until restart. Withdraw remaining credits with that key if needed.'));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../../src/cli/commands/buyer/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/buyer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/buyer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB5D"}
|
|
@@ -10,6 +10,7 @@ import { registerBuyerChannelsCommand } from './channels.js';
|
|
|
10
10
|
import { registerBuyerActivityCommand } from './activity.js';
|
|
11
11
|
import { registerBuyerMeteringCommand } from './metering.js';
|
|
12
12
|
import { registerBuyerEmissionsCommand } from './emissions.js';
|
|
13
|
+
import { registerBuyerIdentityCommands } from './identity.js';
|
|
13
14
|
export function registerBuyerCommands(program) {
|
|
14
15
|
const buyerCmd = program
|
|
15
16
|
.command('buyer')
|
|
@@ -26,5 +27,6 @@ export function registerBuyerCommands(program) {
|
|
|
26
27
|
registerBuyerActivityCommand(buyerCmd);
|
|
27
28
|
registerBuyerMeteringCommand(buyerCmd);
|
|
28
29
|
registerBuyerEmissionsCommand(buyerCmd);
|
|
30
|
+
registerBuyerIdentityCommands(buyerCmd);
|
|
29
31
|
}
|
|
30
32
|
//# sourceMappingURL=index.js.map
|