@tabai/sdk 0.2.1 → 0.2.3
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 +8 -5
- package/dist/_shared/chains.d.ts +2 -2
- package/dist/_shared/chains.js +1 -1
- package/dist/_shared/chains.js.map +1 -1
- package/dist/mcp/assets.js +1 -1
- package/dist/mcp/assets.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,9 +79,12 @@ The one failure worth handling by name is an agent with no headroom:
|
|
|
79
79
|
|
|
80
80
|
Both figures are present only on `LIMIT_EXCEEDED`, and they are there so the answer is actionable. **The correct response is to settle, not to retry**: retrying a call that exceeded a credit limit produces the same refusal at the same cost. A Settlement restores headroom in the block it lands.
|
|
81
81
|
|
|
82
|
-
### A new agent
|
|
82
|
+
### A new agent starts at the baseline, and earns the rest
|
|
83
83
|
|
|
84
|
-
A credit limit is capped by the Bonds of
|
|
84
|
+
A credit limit is capped by the Bonds of the Services the agent deals with, and a Service the agent has authorised counts as one before any Settlement.
|
|
85
|
+
So a brand-new agent that authorises a bonded Service starts at `min(baseline, 95% of that Service's free Bond)`: the Service's own decision to carry a stranger, backed by its own stake.
|
|
86
|
+
Anything above the baseline is earned, by settled history with at least three Curated, bonded Services.
|
|
87
|
+
An agent that has authorised nobody has no counterparties and no limit.
|
|
85
88
|
|
|
86
89
|
---
|
|
87
90
|
|
|
@@ -123,7 +126,7 @@ Add --broadcast to send it. This spends real funds.
|
|
|
123
126
|
|
|
124
127
|
## Configuration
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
Two things are yours to name, and both live in a config file rather than the environment, because neither is a secret: the agent whose Open Tab a call meters to, and any Service beyond the hosted demo one. `doctor` warns when the agent is missing.
|
|
127
130
|
|
|
128
131
|
Put a `tab.config.mjs` beside your project, or in any parent directory:
|
|
129
132
|
|
|
@@ -184,7 +187,7 @@ The key is read at the moment a Settlement is built, and never from this file. `
|
|
|
184
187
|
|
|
185
188
|
| Variable | Needed for |
|
|
186
189
|
| --- | --- |
|
|
187
|
-
| `MONAD_RPC_URL` |
|
|
190
|
+
| `MONAD_RPC_URL` | `doctor`'s chain checks and a Settlement signer. The MCP tools read through the registry API |
|
|
188
191
|
| `MONAD_CHAIN_ID` | `143` for Mainnet, `10143` for Testnet. Defaults to Testnet |
|
|
189
192
|
| `TAB_BOOK_ADDRESS`, `TAB_SETTLEMENT_ADDRESS`, `SERVICE_REGISTRY_ADDRESS`, `BOND_ADDRESS` | resolving credit, Services and Bond |
|
|
190
193
|
| `NEXT_PUBLIC_REGISTRY_API_URL` | the Service directory and an agent's history. Defaults to the project's hosted registry for the chosen network |
|
|
@@ -308,7 +311,7 @@ app.all("/hub/nansen/*", (c) => proxy(c.req.raw));
|
|
|
308
311
|
|
|
309
312
|
The price is known only after the upstream's `402`, so `pricing` is a book the forward writes and `priceOf` reads, keyed by the request. **The amount rides in the unit count, not the unit price.** `TabBook.recordDelivery` refuses any unit price the applied price list does not hold, and a fronted price varies per call, so the Service publishes a small fixed unit for the fronted tool, one base unit by default, and a call consumes as many units as it cost. Without that published price every fronted delivery reverts `UnknownTool`, the plugin delivers anyway because a broken price list is the Service's fault, and the Service pays the upstream for work it bills nobody. `unitBaseUnits` sets a coarser unit, rounded up so the Service is never left short. `preflight` runs between the upstream's `402` and the operator's signature, with the quoted amount in hand: a Service simulates the delivery against `TabBook` there and refuses an Agent with no headroom before its own funds move. Only `exact` with EIP-3009 is signed, on the Service's own chain and Asset; an upstream that accepts nothing the Service can pay in is answered with why, and nothing is metered.
|
|
310
313
|
|
|
311
|
-
`fetchHubManifest` reads Monad's API Hub, which fronts
|
|
314
|
+
`fetchHubManifest` reads Monad's API Hub, which fronts dozens of pay-per-request providers behind one x402 endpoint, and `tab_discover` lists a fronted provider's endpoints under the Service as the tools they are, with the Hub's per-call price in base units:
|
|
312
315
|
|
|
313
316
|
```js
|
|
314
317
|
services: [{ serviceId, endpoint, hub: { provider: "defillama", prefix: "apihub" } }]
|
package/dist/_shared/chains.d.ts
CHANGED
|
@@ -104,7 +104,7 @@ export interface TabHosted {
|
|
|
104
104
|
readonly registryUrl: string;
|
|
105
105
|
readonly demoService: HostedService;
|
|
106
106
|
/** The test token the hosted deployment prices in, where it ships one: `mUSDC`, 6 decimals. */
|
|
107
|
-
readonly
|
|
107
|
+
readonly testAsset?: Address;
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* The read API and the demo Service this project runs, per network.
|
|
@@ -130,7 +130,7 @@ export declare const TAB_HOSTED: {
|
|
|
130
130
|
readonly name: "tab.demo";
|
|
131
131
|
readonly endpoint: "https://gateway-testnet-production-a657.up.railway.app";
|
|
132
132
|
};
|
|
133
|
-
readonly
|
|
133
|
+
readonly testAsset: "0x480209747417f5c830fDA188a9b9AcFa70Bc4083";
|
|
134
134
|
};
|
|
135
135
|
};
|
|
136
136
|
/** The two ERC-8004 registries a Tab deployment reads and writes. */
|
package/dist/_shared/chains.js
CHANGED
|
@@ -85,7 +85,7 @@ export const TAB_HOSTED = {
|
|
|
85
85
|
name: "tab.demo",
|
|
86
86
|
endpoint: "https://gateway-testnet-production-a657.up.railway.app",
|
|
87
87
|
},
|
|
88
|
-
|
|
88
|
+
testAsset: "0x480209747417f5c830fDA188a9b9AcFa70Bc4083",
|
|
89
89
|
},
|
|
90
90
|
};
|
|
91
91
|
/** The canonical ERC-8004 registries, keyed by chain id. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Chain and Asset constants for Tab on Monad.\n *\n * Tab runs on one chain. The Agent's payment and the ledger entry happen in the\n * same Monad transaction, so nothing in the system refers to any other chain.\n * What this module carries is which Monad network a deployment targets and\n * which Assets it settles in.\n *\n * Addresses of Tab's own contracts are deployment output and live in\n * `deployments.json`, never here.\n */\nimport type { Address, Bytes32 } from \"./hex.js\";\n\n/** A Monad network a Tab deployment can target. */\nexport interface ChainDescriptor {\n readonly name: string;\n readonly chainId: number;\n readonly rpcUrl: string;\n readonly explorerUrl: string;\n /** The MON faucet, testnet only. */\n readonly faucetUrl?: string;\n}\n\nexport const MONAD_MAINNET = {\n name: \"Monad Mainnet\",\n chainId: 143,\n rpcUrl: \"https://rpc.monad.xyz\",\n explorerUrl: \"https://monadvision.com\",\n} as const satisfies ChainDescriptor;\n\nexport const MONAD_TESTNET = {\n name: \"Monad Testnet\",\n chainId: 10143,\n rpcUrl: \"https://testnet-rpc.monad.xyz\",\n explorerUrl: \"https://testnet.monadvision.com\",\n faucetUrl: \"https://faucet.monad.xyz\",\n} as const satisfies ChainDescriptor;\n\nexport const CHAINS = {\n [MONAD_MAINNET.chainId]: MONAD_MAINNET,\n [MONAD_TESTNET.chainId]: MONAD_TESTNET,\n} as const;\n\nexport type MonadChainId = keyof typeof CHAINS;\n\nexport function isMonadChainId(value: unknown): value is MonadChainId {\n return value === MONAD_MAINNET.chainId || value === MONAD_TESTNET.chainId;\n}\n\nexport function chainFor(chainId: number | bigint): ChainDescriptor | undefined {\n const narrowed = typeof chainId === \"bigint\" ? Number(chainId) : chainId;\n return isMonadChainId(narrowed) ? CHAINS[narrowed] : undefined;\n}\n\n/** Link to an address or a transaction on the explorer for a chain. */\nexport function explorerLink(chain: ChainDescriptor, kind: \"address\" | \"tx\", hash: string): string {\n return `${chain.explorerUrl}/${kind}/${hash}`;\n}\n\n/** A stablecoin Tab settles in. Amounts everywhere are integer base units. */\nexport interface AssetDescriptor {\n readonly symbol: string;\n readonly decimals: number;\n readonly address: Address;\n}\n\n/** Canonical stablecoins on Monad Mainnet. */\nexport const MAINNET_ASSETS = {\n USDC: {\n symbol: \"USDC\",\n decimals: 6,\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n },\n AUSD: {\n symbol: \"AUSD\",\n decimals: 6,\n address: \"0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a\",\n },\n} as const satisfies Readonly<Record<string, AssetDescriptor>>;\n\n/**\n * Stablecoins on Monad Testnet. `USDC` is Circle's own testnet deployment\n * (`name` \"USDC\", EIP-712 version \"2\", 20 USDC per address every two hours from\n * https://faucet.circle.com). `MockUsdc`, the mintable test double the deploy\n * script ships, is a deployment output and lives in `deployments.json`.\n */\nexport const TESTNET_ASSETS = {\n USDC: {\n symbol: \"USDC\",\n decimals: 6,\n address: \"0x534b2f3A21130d7a60830c2Df862319e593943A3\",\n },\n} as const satisfies Readonly<Record<string, AssetDescriptor>>;\n\n/**\n * Uniswap's Permit2, at its canonical address on every chain it was deployed\n * to, Monad Mainnet and Testnet included. `TabSettlement.settleWithPermit2`\n * verifies an Agent's signature against it, so an Agent approves Permit2 once\n * and signs thereafter.\n */\nexport const PERMIT2_ADDRESS = \"0x000000000022D473030F116dDEE9F6B43aC78BA3\" as const satisfies Address;\n\n/** The x402 facilitator that verifies and settles `exact` payments on Monad. */\nexport const X402_FACILITATOR_URL = \"https://x402-facilitator.molandak.org\" as const;\n\n/** A Service this project hosts, and where it is reached. */\nexport interface HostedService {\n readonly serviceId: Bytes32;\n readonly name: string;\n readonly endpoint: string;\n}\n\n/** What this project hosts on one network: the read API and the demo Service. */\nexport interface TabHosted {\n readonly registryUrl: string;\n readonly demoService: HostedService;\n /** The test token the hosted deployment prices in, where it ships one: `mUSDC`, 6 decimals. */\n readonly testToken?: Address;\n}\n\n/**\n * The read API and the demo Service this project runs, per network.\n *\n * Defaults, never authority: the chain is the authority on every figure, and a\n * configured `registryUrl` or `services` entry always wins over these. They are\n * here so that a fresh install can discover and call something before its owner\n * has configured anything, which is the first thing anyone tries.\n */\nexport const TAB_HOSTED = {\n [MONAD_MAINNET.chainId]: {\n registryUrl: \"https://registry-mainnet-production.up.railway.app\",\n demoService: {\n serviceId: \"0x7461622e64656d6f000000000000000000000000000000000000000000000000\",\n name: \"tab.demo\",\n endpoint: \"https://gateway-mainnet-production.up.railway.app\",\n },\n },\n [MONAD_TESTNET.chainId]: {\n registryUrl: \"https://registry-testnet-production.up.railway.app\",\n demoService: {\n serviceId: \"0x7461622e64656d6f000000000000000000000000000000000000000000000000\",\n name: \"tab.demo\",\n endpoint: \"https://gateway-testnet-production-a657.up.railway.app\",\n },\n testToken: \"0x480209747417f5c830fDA188a9b9AcFa70Bc4083\",\n },\n} as const satisfies Readonly<Record<MonadChainId, TabHosted>>;\n\n/** The two ERC-8004 registries a Tab deployment reads and writes. */\nexport interface Erc8004Registries {\n /** Agent identities: an ERC-721 whose token id is the agentId and whose URI is the registration file. */\n readonly identity: Address;\n /** Feedback about agents, keyed by agentId and client. */\n readonly reputation: Address;\n}\n\n/** The canonical ERC-8004 registries, keyed by chain id. */\nexport const ERC8004_REGISTRIES = {\n [MONAD_MAINNET.chainId]: {\n identity: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n reputation: \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\",\n },\n [MONAD_TESTNET.chainId]: {\n identity: \"0x8004A818BFB912233c491871b3d84c89A494BD9e\",\n reputation: \"0x8004B663056A597Dffe9eCcC1965A193B7388713\",\n },\n} as const satisfies Readonly<Record<MonadChainId, Erc8004Registries>>;\n\nexport function erc8004RegistriesFor(chainId: number | bigint): Erc8004Registries | undefined {\n const narrowed = typeof chainId === \"bigint\" ? Number(chainId) : chainId;\n return isMonadChainId(narrowed) ? ERC8004_REGISTRIES[narrowed] : undefined;\n}\n\nexport const PLACEHOLDER_ADDRESS = \"0x0000000000000000000000000000000000000000\" as const;\n\n/** Formats base units of a six-decimal Asset for display, without floating point. */\nexport function formatBaseUnits(amount: bigint, decimals: number): string {\n const negative = amount < 0n;\n const abs = negative ? -amount : amount;\n const scale = 10n ** BigInt(decimals);\n const whole = abs / scale;\n const fraction = (abs % scale).toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n return `${negative ? \"-\" : \"\"}${whole}${fraction ? `.${fraction}` : \"\"}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Chain and Asset constants for Tab on Monad.\n *\n * Tab runs on one chain. The Agent's payment and the ledger entry happen in the\n * same Monad transaction, so nothing in the system refers to any other chain.\n * What this module carries is which Monad network a deployment targets and\n * which Assets it settles in.\n *\n * Addresses of Tab's own contracts are deployment output and live in\n * `deployments.json`, never here.\n */\nimport type { Address, Bytes32 } from \"./hex.js\";\n\n/** A Monad network a Tab deployment can target. */\nexport interface ChainDescriptor {\n readonly name: string;\n readonly chainId: number;\n readonly rpcUrl: string;\n readonly explorerUrl: string;\n /** The MON faucet, testnet only. */\n readonly faucetUrl?: string;\n}\n\nexport const MONAD_MAINNET = {\n name: \"Monad Mainnet\",\n chainId: 143,\n rpcUrl: \"https://rpc.monad.xyz\",\n explorerUrl: \"https://monadvision.com\",\n} as const satisfies ChainDescriptor;\n\nexport const MONAD_TESTNET = {\n name: \"Monad Testnet\",\n chainId: 10143,\n rpcUrl: \"https://testnet-rpc.monad.xyz\",\n explorerUrl: \"https://testnet.monadvision.com\",\n faucetUrl: \"https://faucet.monad.xyz\",\n} as const satisfies ChainDescriptor;\n\nexport const CHAINS = {\n [MONAD_MAINNET.chainId]: MONAD_MAINNET,\n [MONAD_TESTNET.chainId]: MONAD_TESTNET,\n} as const;\n\nexport type MonadChainId = keyof typeof CHAINS;\n\nexport function isMonadChainId(value: unknown): value is MonadChainId {\n return value === MONAD_MAINNET.chainId || value === MONAD_TESTNET.chainId;\n}\n\nexport function chainFor(chainId: number | bigint): ChainDescriptor | undefined {\n const narrowed = typeof chainId === \"bigint\" ? Number(chainId) : chainId;\n return isMonadChainId(narrowed) ? CHAINS[narrowed] : undefined;\n}\n\n/** Link to an address or a transaction on the explorer for a chain. */\nexport function explorerLink(chain: ChainDescriptor, kind: \"address\" | \"tx\", hash: string): string {\n return `${chain.explorerUrl}/${kind}/${hash}`;\n}\n\n/** A stablecoin Tab settles in. Amounts everywhere are integer base units. */\nexport interface AssetDescriptor {\n readonly symbol: string;\n readonly decimals: number;\n readonly address: Address;\n}\n\n/** Canonical stablecoins on Monad Mainnet. */\nexport const MAINNET_ASSETS = {\n USDC: {\n symbol: \"USDC\",\n decimals: 6,\n address: \"0x754704Bc059F8C67012fEd69BC8A327a5aafb603\",\n },\n AUSD: {\n symbol: \"AUSD\",\n decimals: 6,\n address: \"0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a\",\n },\n} as const satisfies Readonly<Record<string, AssetDescriptor>>;\n\n/**\n * Stablecoins on Monad Testnet. `USDC` is Circle's own testnet deployment\n * (`name` \"USDC\", EIP-712 version \"2\", 20 USDC per address every two hours from\n * https://faucet.circle.com). `MockUsdc`, the mintable test double the deploy\n * script ships, is a deployment output and lives in `deployments.json`.\n */\nexport const TESTNET_ASSETS = {\n USDC: {\n symbol: \"USDC\",\n decimals: 6,\n address: \"0x534b2f3A21130d7a60830c2Df862319e593943A3\",\n },\n} as const satisfies Readonly<Record<string, AssetDescriptor>>;\n\n/**\n * Uniswap's Permit2, at its canonical address on every chain it was deployed\n * to, Monad Mainnet and Testnet included. `TabSettlement.settleWithPermit2`\n * verifies an Agent's signature against it, so an Agent approves Permit2 once\n * and signs thereafter.\n */\nexport const PERMIT2_ADDRESS = \"0x000000000022D473030F116dDEE9F6B43aC78BA3\" as const satisfies Address;\n\n/** The x402 facilitator that verifies and settles `exact` payments on Monad. */\nexport const X402_FACILITATOR_URL = \"https://x402-facilitator.molandak.org\" as const;\n\n/** A Service this project hosts, and where it is reached. */\nexport interface HostedService {\n readonly serviceId: Bytes32;\n readonly name: string;\n readonly endpoint: string;\n}\n\n/** What this project hosts on one network: the read API and the demo Service. */\nexport interface TabHosted {\n readonly registryUrl: string;\n readonly demoService: HostedService;\n /** The test token the hosted deployment prices in, where it ships one: `mUSDC`, 6 decimals. */\n readonly testAsset?: Address;\n}\n\n/**\n * The read API and the demo Service this project runs, per network.\n *\n * Defaults, never authority: the chain is the authority on every figure, and a\n * configured `registryUrl` or `services` entry always wins over these. They are\n * here so that a fresh install can discover and call something before its owner\n * has configured anything, which is the first thing anyone tries.\n */\nexport const TAB_HOSTED = {\n [MONAD_MAINNET.chainId]: {\n registryUrl: \"https://registry-mainnet-production.up.railway.app\",\n demoService: {\n serviceId: \"0x7461622e64656d6f000000000000000000000000000000000000000000000000\",\n name: \"tab.demo\",\n endpoint: \"https://gateway-mainnet-production.up.railway.app\",\n },\n },\n [MONAD_TESTNET.chainId]: {\n registryUrl: \"https://registry-testnet-production.up.railway.app\",\n demoService: {\n serviceId: \"0x7461622e64656d6f000000000000000000000000000000000000000000000000\",\n name: \"tab.demo\",\n endpoint: \"https://gateway-testnet-production-a657.up.railway.app\",\n },\n testAsset: \"0x480209747417f5c830fDA188a9b9AcFa70Bc4083\",\n },\n} as const satisfies Readonly<Record<MonadChainId, TabHosted>>;\n\n/** The two ERC-8004 registries a Tab deployment reads and writes. */\nexport interface Erc8004Registries {\n /** Agent identities: an ERC-721 whose token id is the agentId and whose URI is the registration file. */\n readonly identity: Address;\n /** Feedback about agents, keyed by agentId and client. */\n readonly reputation: Address;\n}\n\n/** The canonical ERC-8004 registries, keyed by chain id. */\nexport const ERC8004_REGISTRIES = {\n [MONAD_MAINNET.chainId]: {\n identity: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n reputation: \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\",\n },\n [MONAD_TESTNET.chainId]: {\n identity: \"0x8004A818BFB912233c491871b3d84c89A494BD9e\",\n reputation: \"0x8004B663056A597Dffe9eCcC1965A193B7388713\",\n },\n} as const satisfies Readonly<Record<MonadChainId, Erc8004Registries>>;\n\nexport function erc8004RegistriesFor(chainId: number | bigint): Erc8004Registries | undefined {\n const narrowed = typeof chainId === \"bigint\" ? Number(chainId) : chainId;\n return isMonadChainId(narrowed) ? ERC8004_REGISTRIES[narrowed] : undefined;\n}\n\nexport const PLACEHOLDER_ADDRESS = \"0x0000000000000000000000000000000000000000\" as const;\n\n/** Formats base units of a six-decimal Asset for display, without floating point. */\nexport function formatBaseUnits(amount: bigint, decimals: number): string {\n const negative = amount < 0n;\n const abs = negative ? -amount : amount;\n const scale = 10n ** BigInt(decimals);\n const whole = abs / scale;\n const fraction = (abs % scale).toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n return `${negative ? \"-\" : \"\"}${whole}${fraction ? `.${fraction}` : \"\"}`;\n}\n"]}
|
package/dist/mcp/assets.js
CHANGED
|
@@ -29,7 +29,7 @@ function knownAssets(chainId, env) {
|
|
|
29
29
|
// hosted Testnet deployment's is known without it, so a fresh install
|
|
30
30
|
// shows `mUSDC` rather than an address with no symbol.
|
|
31
31
|
const configured = env["MOCK_USDC_ADDRESS"];
|
|
32
|
-
const mock = configured !== undefined && isAddress(configured) ? configured : TAB_HOSTED[MONAD_TESTNET.chainId].
|
|
32
|
+
const mock = configured !== undefined && isAddress(configured) ? configured : TAB_HOSTED[MONAD_TESTNET.chainId].testAsset;
|
|
33
33
|
return mock !== undefined ? [...known, { address: mock.toLowerCase(), symbol: "mUSDC", decimals: 6 }] : known;
|
|
34
34
|
}
|
|
35
35
|
return [];
|
package/dist/mcp/assets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/mcp/assets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Assets at the MCP boundary.\n *\n * An Asset is named to a model as `<chainId>:<address>`, the same shape the\n * `Tab-Charge-Asset` header carries, so the string a tool result shows is the\n * string a tool argument accepts. `TabBook` keys an Asset by token address alone;\n * the chain id travels with it here because the SDK can be pointed at Monad\n * Mainnet or Monad Testnet and a bare address is ambiguous between the two.\n *\n * The canonical stablecoins are known by symbol and decimals. Any other address\n * is still a valid Asset, it is just one this SDK has no facts about, and the\n * tool results say so rather than guessing.\n */\nimport type { Address, Result } from \"../_shared/index.js\";\nimport { MAINNET_ASSETS, MONAD_MAINNET, MONAD_TESTNET, TAB_HOSTED, TESTNET_ASSETS, isAddress, ok } from \"../_shared/index.js\";\nimport { validationError } from \"../errors.js\";\nimport type { AssetRef } from \"../payments/strategy.js\";\n\nexport type AssetString = string;\n\nexport interface AssetFacts {\n readonly chainId: number;\n readonly address: Address;\n readonly symbol: string | null;\n readonly decimals: number | null;\n /** True when the address is a canonical stablecoin on that chain, or a configured test token. */\n readonly curatedAsset: boolean;\n}\n\nexport const formatAsset = (chainId: bigint | number, address: string): AssetString =>\n `${String(chainId)}:${address.toLowerCase()}`;\n\nexport const assetStringOf = (asset: AssetRef): AssetString => formatAsset(asset.chainId, asset.address);\n\n/** The chain ids this SDK knows how to describe. */\nexport const KNOWN_CHAIN_IDS = [MONAD_MAINNET.chainId, MONAD_TESTNET.chainId] as const;\n\n/**\n * The stablecoins this SDK can name, per chain. On Testnet that is Circle's\n * USDC from the shared table plus the mock token the deployment shipped, read\n * from `MOCK_USDC_ADDRESS` or, failing that, the hosted deployment's. The mock is named `mUSDC` here although its own\n * `symbol()` says `USDC`, because a Service that accepts both must show two\n * Assets and not one word twice.\n */\nfunction knownAssets(chainId: number, env: NodeJS.ProcessEnv): readonly { address: string; symbol: string; decimals: number }[] {\n if (chainId === MONAD_MAINNET.chainId) {\n return Object.values(MAINNET_ASSETS).map((asset) => ({\n address: asset.address.toLowerCase(),\n symbol: asset.symbol,\n decimals: asset.decimals,\n }));\n }\n if (chainId === MONAD_TESTNET.chainId) {\n const known = Object.values(TESTNET_ASSETS).map((asset) => ({\n address: asset.address.toLowerCase(),\n symbol: asset.symbol,\n decimals: asset.decimals,\n }));\n // The environment names the test token for a deployment of its own; the\n // hosted Testnet deployment's is known without it, so a fresh install\n // shows `mUSDC` rather than an address with no symbol.\n const configured = env[\"MOCK_USDC_ADDRESS\"];\n const mock = configured !== undefined && isAddress(configured) ? configured : TAB_HOSTED[MONAD_TESTNET.chainId].
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/mcp/assets.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAc/C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAwB,EAAE,OAAe,EAAe,EAAE,CACpF,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;AAEhD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAe,EAAe,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AAEzG,oDAAoD;AACpD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAU,CAAC;AAEvF;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,OAAe,EAAE,GAAsB;IAC1D,IAAI,OAAO,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACnD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;YACpC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IACD,IAAI,OAAO,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1D,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;YACpC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC,CAAC,CAAC;QACJ,wEAAwE;QACxE,sEAAsE;QACtE,uDAAuD;QACvD,MAAM,UAAU,GAAG,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,UAAU,KAAK,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC;QAC1H,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAChH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc,EAAE,KAAK,GAAG,OAAO,EAAE,MAAyB,OAAO,CAAC,GAAG;IAC9F,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,eAAe,CAAC,iBAAiB,EAAE,GAAG,KAAK,gEAAgE,OAAO,KAAK,EAAE,EAAE;YAChI,OAAO,EAAE,EAAE,KAAK,EAAE;SACnB,CAAC,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,OAAO,eAAe,CACpB,iBAAiB,EACjB,GAAG,KAAK,kDAAkD,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,gBAAgB,KAAK,IAAI,EAC5H,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAC9B,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,OAAO,eAAe,CAAC,0BAA0B,EAAE,GAAG,KAAK,mDAAmD,UAAU,IAAI,EAAE;YAC5H,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE;SACxC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,eAAe,CAAC,yBAAyB,EAAE,GAAG,KAAK,iDAAiD,UAAU,IAAI,EAAE;YACzH,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE;SACxC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,CAAE,eAAqC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,OAAO,eAAe,CACpB,yBAAyB,EACzB,YAAY,UAAU,kDAAkD,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EACvG,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,EAAE,CAAC;QACR,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;QACxB,OAAO,EAAE,UAAU,CAAC,WAAW,EAAa;QAC5C,4EAA4E;QAC5E,kEAAkE;QAClE,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC;QAC7B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,OAAO;KAChC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAwB,EAAE,OAAe,EAAE,MAAyB,OAAO,CAAC,GAAG;IACxG,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAa,CAAC;IACjD,MAAM,OAAO,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACxE,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IACnF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACpH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AACnG,CAAC","sourcesContent":["/**\n * Assets at the MCP boundary.\n *\n * An Asset is named to a model as `<chainId>:<address>`, the same shape the\n * `Tab-Charge-Asset` header carries, so the string a tool result shows is the\n * string a tool argument accepts. `TabBook` keys an Asset by token address alone;\n * the chain id travels with it here because the SDK can be pointed at Monad\n * Mainnet or Monad Testnet and a bare address is ambiguous between the two.\n *\n * The canonical stablecoins are known by symbol and decimals. Any other address\n * is still a valid Asset, it is just one this SDK has no facts about, and the\n * tool results say so rather than guessing.\n */\nimport type { Address, Result } from \"../_shared/index.js\";\nimport { MAINNET_ASSETS, MONAD_MAINNET, MONAD_TESTNET, TAB_HOSTED, TESTNET_ASSETS, isAddress, ok } from \"../_shared/index.js\";\nimport { validationError } from \"../errors.js\";\nimport type { AssetRef } from \"../payments/strategy.js\";\n\nexport type AssetString = string;\n\nexport interface AssetFacts {\n readonly chainId: number;\n readonly address: Address;\n readonly symbol: string | null;\n readonly decimals: number | null;\n /** True when the address is a canonical stablecoin on that chain, or a configured test token. */\n readonly curatedAsset: boolean;\n}\n\nexport const formatAsset = (chainId: bigint | number, address: string): AssetString =>\n `${String(chainId)}:${address.toLowerCase()}`;\n\nexport const assetStringOf = (asset: AssetRef): AssetString => formatAsset(asset.chainId, asset.address);\n\n/** The chain ids this SDK knows how to describe. */\nexport const KNOWN_CHAIN_IDS = [MONAD_MAINNET.chainId, MONAD_TESTNET.chainId] as const;\n\n/**\n * The stablecoins this SDK can name, per chain. On Testnet that is Circle's\n * USDC from the shared table plus the mock token the deployment shipped, read\n * from `MOCK_USDC_ADDRESS` or, failing that, the hosted deployment's. The mock is named `mUSDC` here although its own\n * `symbol()` says `USDC`, because a Service that accepts both must show two\n * Assets and not one word twice.\n */\nfunction knownAssets(chainId: number, env: NodeJS.ProcessEnv): readonly { address: string; symbol: string; decimals: number }[] {\n if (chainId === MONAD_MAINNET.chainId) {\n return Object.values(MAINNET_ASSETS).map((asset) => ({\n address: asset.address.toLowerCase(),\n symbol: asset.symbol,\n decimals: asset.decimals,\n }));\n }\n if (chainId === MONAD_TESTNET.chainId) {\n const known = Object.values(TESTNET_ASSETS).map((asset) => ({\n address: asset.address.toLowerCase(),\n symbol: asset.symbol,\n decimals: asset.decimals,\n }));\n // The environment names the test token for a deployment of its own; the\n // hosted Testnet deployment's is known without it, so a fresh install\n // shows `mUSDC` rather than an address with no symbol.\n const configured = env[\"MOCK_USDC_ADDRESS\"];\n const mock = configured !== undefined && isAddress(configured) ? configured : TAB_HOSTED[MONAD_TESTNET.chainId].testAsset;\n return mock !== undefined ? [...known, { address: mock.toLowerCase(), symbol: \"mUSDC\", decimals: 6 }] : known;\n }\n return [];\n}\n\nexport function parseAsset(value: unknown, label = \"asset\", env: NodeJS.ProcessEnv = process.env): Result<AssetRef> {\n if (typeof value !== \"string\") {\n return validationError(\"ASSET_MALFORMED\", `${label} must be a string of the form chainId:tokenAddress, received ${typeof value}`, {\n details: { label },\n });\n }\n const colon = value.indexOf(\":\");\n if (colon <= 0) {\n return validationError(\n \"ASSET_MALFORMED\",\n `${label} must be chainId:tokenAddress, for example 143:${MAINNET_ASSETS.USDC.address.toLowerCase()}, received \\`${value}\\``,\n { details: { label, value } },\n );\n }\n const rawChainId = value.slice(0, colon);\n const rawAddress = value.slice(colon + 1);\n if (!/^[0-9]+$/.test(rawChainId)) {\n return validationError(\"ASSET_CHAIN_ID_MALFORMED\", `${label} must start with a decimal chain id, received \\`${rawChainId}\\``, {\n details: { label, chainId: rawChainId },\n });\n }\n if (!isAddress(rawAddress)) {\n return validationError(\"ASSET_ADDRESS_MALFORMED\", `${label} must end in a 20-byte 0x address, received \\`${rawAddress}\\``, {\n details: { label, address: rawAddress },\n });\n }\n const chainId = Number(rawChainId);\n if (!(KNOWN_CHAIN_IDS as readonly number[]).includes(chainId)) {\n return validationError(\n \"ASSET_CHAIN_UNSUPPORTED\",\n `chain id ${rawChainId} is not a Monad network; the supported ids are ${KNOWN_CHAIN_IDS.join(\" and \")}`,\n { details: { label, chainId: rawChainId, supported: KNOWN_CHAIN_IDS.join(\", \") } },\n );\n }\n const facts = assetFacts(chainId, rawAddress, env);\n return ok({\n chainId: BigInt(chainId),\n address: rawAddress.toLowerCase() as Address,\n // An unknown token is assumed to be a six-decimal stablecoin, which is what\n // every Asset Tab settles in. The facts say when that is a guess.\n decimals: facts.decimals ?? 6,\n symbol: facts.symbol ?? \"TOKEN\",\n });\n}\n\nexport function assetFacts(chainId: bigint | number, address: string, env: NodeJS.ProcessEnv = process.env): AssetFacts {\n const lowered = address.toLowerCase() as Address;\n const numeric = typeof chainId === \"bigint\" ? Number(chainId) : chainId;\n const known = knownAssets(numeric, env).find((asset) => asset.address === lowered);\n if (known !== undefined) {\n return { chainId: numeric, address: lowered, symbol: known.symbol, decimals: known.decimals, curatedAsset: true };\n }\n return { chainId: numeric, address: lowered, symbol: null, decimals: null, curatedAsset: false };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tabai/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Post-paid billing for autonomous agents on Monad. MCP server, CLI and TypeScript SDK: call a priced tool now, settle in USDC later, and let TabSettlement apply the payment to the tab in the same transaction.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"monad",
|