crumb-alpha-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test.log +38 -0
- package/dist/commands/balance.d.ts +2 -0
- package/dist/commands/balance.d.ts.map +1 -0
- package/dist/commands/balance.js +43 -0
- package/dist/commands/balance.js.map +1 -0
- package/dist/commands/deposit.d.ts +2 -0
- package/dist/commands/deposit.d.ts.map +1 -0
- package/dist/commands/deposit.js +52 -0
- package/dist/commands/deposit.js.map +1 -0
- package/dist/commands/history.d.ts +4 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +10 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +76 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pay.d.ts +4 -0
- package/dist/commands/pay.d.ts.map +1 -0
- package/dist/commands/pay.js +50 -0
- package/dist/commands/pay.js.map +1 -0
- package/dist/commands/serve.d.ts +5 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +43 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/wallet.d.ts +4 -0
- package/dist/commands/wallet.d.ts.map +1 -0
- package/dist/commands/wallet.js +69 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/commands/withdraw.d.ts +4 -0
- package/dist/commands/withdraw.d.ts.map +1 -0
- package/dist/commands/withdraw.js +54 -0
- package/dist/commands/withdraw.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +30 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/keystore.d.ts +5 -0
- package/dist/utils/keystore.d.ts.map +1 -0
- package/dist/utils/keystore.js +51 -0
- package/dist/utils/keystore.js.map +1 -0
- package/dist/utils/output.d.ts +8 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +35 -0
- package/dist/utils/output.js.map +1 -0
- package/package.json +39 -0
- package/src/commands/balance.ts +48 -0
- package/src/commands/deposit.ts +57 -0
- package/src/commands/history.ts +11 -0
- package/src/commands/init.ts +86 -0
- package/src/commands/pay.ts +55 -0
- package/src/commands/serve.ts +58 -0
- package/src/commands/wallet.ts +81 -0
- package/src/commands/withdraw.ts +62 -0
- package/src/index.ts +83 -0
- package/src/utils/config.ts +41 -0
- package/src/utils/keystore.ts +65 -0
- package/src/utils/output.ts +40 -0
- package/test/config.test.ts +109 -0
- package/test/keystore.test.ts +118 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @crumb/cli@0.1.0 test /Users/taylorferran/Desktop/dev/crumb-sdk/packages/cli
|
|
4
|
+
> vitest run
|
|
5
|
+
|
|
6
|
+
[?25l
|
|
7
|
+
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/Users/taylorferran/Desktop/dev/crumb-sdk/packages/cli[39m
|
|
8
|
+
|
|
9
|
+
[?2026h
|
|
10
|
+
[1m[33m ❯ [39m[22mtest/config.test.ts[2m [queued][22m
|
|
11
|
+
|
|
12
|
+
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (2)[39m
|
|
13
|
+
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (0)[39m
|
|
14
|
+
[2m Start at [22m11:08:55
|
|
15
|
+
[2m Duration [22m101ms
|
|
16
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m test/config.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
17
|
+
|
|
18
|
+
[1m[33m ❯ [39m[22mtest/keystore.test.ts[2m 1/10[22m
|
|
19
|
+
|
|
20
|
+
[2m Test Files [22m[1m[32m1 passed[39m[22m[90m (2)[39m
|
|
21
|
+
[2m Tests [22m[1m[32m8 passed[39m[22m[90m (17)[39m
|
|
22
|
+
[2m Start at [22m11:08:55
|
|
23
|
+
[2m Duration [22m202ms
|
|
24
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K
|
|
25
|
+
[1m[33m ❯ [39m[22mtest/keystore.test.ts[2m 4/10[22m
|
|
26
|
+
|
|
27
|
+
[2m Test Files [22m[1m[32m1 passed[39m[22m[90m (2)[39m
|
|
28
|
+
[2m Tests [22m[1m[32m11 passed[39m[22m[90m (17)[39m
|
|
29
|
+
[2m Start at [22m11:08:55
|
|
30
|
+
[2m Duration [22m404ms
|
|
31
|
+
[?2026l[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m test/keystore.test.ts [2m([22m[2m10 tests[22m[2m)[22m[33m 401[2mms[22m[39m
|
|
32
|
+
|
|
33
|
+
[2m Test Files [22m [1m[32m2 passed[39m[22m[90m (2)[39m
|
|
34
|
+
[2m Tests [22m [1m[32m17 passed[39m[22m[90m (17)[39m
|
|
35
|
+
[2m Start at [22m 11:08:55
|
|
36
|
+
[2m Duration [22m 547ms[2m (transform 52ms, setup 0ms, import 76ms, tests 405ms, environment 0ms)[22m
|
|
37
|
+
|
|
38
|
+
[?25h
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AAMA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAyCpD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { GatewayClient } from 'crumb-alpha-core';
|
|
2
|
+
import { readConfig } from '../utils/config.js';
|
|
3
|
+
import { loadPrivateKey, getPassword } from '../utils/keystore.js';
|
|
4
|
+
import { heading, error, box, truncateAddress } from '../utils/output.js';
|
|
5
|
+
export async function balanceCommand() {
|
|
6
|
+
const config = readConfig();
|
|
7
|
+
if (!config.activeWallet) {
|
|
8
|
+
heading('Balance');
|
|
9
|
+
error('No wallet configured. Run `crumb init` first.');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
let password;
|
|
13
|
+
try {
|
|
14
|
+
password = getPassword();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
error('No password provided. Set CRUMB_KEYSTORE_PASSWORD env var.');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let privateKey;
|
|
21
|
+
try {
|
|
22
|
+
privateKey = loadPrivateKey(password);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
error(`Failed to decrypt keystore: ${err.message}`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const chain = (config.chain ?? 'arcTestnet');
|
|
29
|
+
const gateway = new GatewayClient({
|
|
30
|
+
chain,
|
|
31
|
+
privateKey: privateKey,
|
|
32
|
+
});
|
|
33
|
+
const balances = await gateway.getBalances();
|
|
34
|
+
box([
|
|
35
|
+
`Wallet ${truncateAddress(config.activeWallet)}`,
|
|
36
|
+
`Chain ${chain}`,
|
|
37
|
+
``,
|
|
38
|
+
`Wallet ${balances.wallet.formatted} USDC`,
|
|
39
|
+
`Gateway ${balances.gateway.formattedAvailable} USDC available`,
|
|
40
|
+
` ${balances.gateway.formattedTotal} USDC total`,
|
|
41
|
+
]);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAwB,MAAM,kBAAkB,CAAA;AAEtE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAY,MAAM,oBAAoB,CAAA;AAEnF,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAE3B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,OAAO,CAAC,SAAS,CAAC,CAAA;QAClB,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACtD,OAAM;IACR,CAAC;IAED,IAAI,QAAgB,CAAA;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,4DAA4D,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IAED,IAAI,UAAkB,CAAA;IACtB,IAAI,CAAC;QACH,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,YAAY,CAAuB,CAAA;IAClE,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,KAAK;QACL,UAAU,EAAE,UAA2B;KACxC,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAA;IAE5C,GAAG,CAAC;QACF,aAAa,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;QACnD,aAAa,KAAK,EAAE;QACpB,EAAE;QACF,aAAa,QAAQ,CAAC,MAAM,CAAC,SAAS,OAAO;QAC7C,aAAa,QAAQ,CAAC,OAAO,CAAC,kBAAkB,iBAAiB;QACjE,aAAa,QAAQ,CAAC,OAAO,CAAC,cAAc,aAAa;KAC1D,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit.d.ts","sourceRoot":"","sources":["../../src/commands/deposit.ts"],"names":[],"mappings":"AAOA,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDlE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { GatewayClient } from 'crumb-alpha-core';
|
|
2
|
+
import { readConfig } from '../utils/config.js';
|
|
3
|
+
import { loadPrivateKey, getPassword } from '../utils/keystore.js';
|
|
4
|
+
import { heading, success, error, info, keyValue } from '../utils/output.js';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
export async function depositCommand(amount) {
|
|
7
|
+
heading('Deposit');
|
|
8
|
+
const config = readConfig();
|
|
9
|
+
if (!config.activeWallet) {
|
|
10
|
+
error('No wallet configured. Run `crumb init` first.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let password;
|
|
14
|
+
try {
|
|
15
|
+
password = getPassword();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
error('No password provided. Set CRUMB_KEYSTORE_PASSWORD env var.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let privateKey;
|
|
22
|
+
try {
|
|
23
|
+
privateKey = loadPrivateKey(password);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
error(`Failed to decrypt keystore: ${err.message}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const chain = (config.chain ?? 'arcTestnet');
|
|
30
|
+
const gateway = new GatewayClient({
|
|
31
|
+
chain,
|
|
32
|
+
privateKey: privateKey,
|
|
33
|
+
});
|
|
34
|
+
info(`Depositing ${amount} USDC into Gateway...`);
|
|
35
|
+
const spinner = ora(' Processing deposit...').start();
|
|
36
|
+
try {
|
|
37
|
+
const result = await gateway.deposit(amount);
|
|
38
|
+
spinner.stop();
|
|
39
|
+
console.log();
|
|
40
|
+
success('Deposited');
|
|
41
|
+
keyValue('Amount:', `${result.formattedAmount} USDC`);
|
|
42
|
+
keyValue('Deposit Tx:', result.depositTxHash);
|
|
43
|
+
if (result.approvalTxHash) {
|
|
44
|
+
keyValue('Approval Tx:', result.approvalTxHash);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
spinner.stop();
|
|
49
|
+
error(`Deposit failed: ${err.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=deposit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit.js","sourceRoot":"","sources":["../../src/commands/deposit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IACjD,OAAO,CAAC,SAAS,CAAC,CAAA;IAElB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACtD,OAAM;IACR,CAAC;IAED,IAAI,QAAgB,CAAA;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,4DAA4D,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IAED,IAAI,UAAkB,CAAA;IACtB,IAAI,CAAC;QACH,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,YAAY,CAAuB,CAAA;IAClE,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,KAAK;QACL,UAAU,EAAE,UAA2B;KACxC,CAAC,CAAA;IAEF,IAAI,CAAC,cAAc,MAAM,uBAAuB,CAAC,CAAA;IACjD,MAAM,OAAO,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAA;IAEtD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC5C,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,WAAW,CAAC,CAAA;QACpB,QAAQ,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,eAAe,OAAO,CAAC,CAAA;QACrD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,CAAA;QAC7C,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,KAAK,CAAC,mBAAmB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAEA,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/E"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { heading, info } from '../utils/output.js';
|
|
2
|
+
export async function historyCommand(options) {
|
|
3
|
+
heading('Transaction History');
|
|
4
|
+
// TODO: Integrate with Arc indexer or local transaction log
|
|
5
|
+
// For now, this is a placeholder that will be implemented once
|
|
6
|
+
// we have access to a transaction indexing API
|
|
7
|
+
info('Transaction history is not yet available.');
|
|
8
|
+
info('This feature will be added in a future release.');
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA2B;IAC9D,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAE9B,4DAA4D;IAC5D,+DAA+D;IAC/D,+CAA+C;IAC/C,IAAI,CAAC,2CAA2C,CAAC,CAAA;IACjD,IAAI,CAAC,iDAAiD,CAAC,CAAA;AACzD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA+EjD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createWallet } from 'crumb-alpha-core';
|
|
2
|
+
import { configExists, writeConfig, getConfigPath } from '../utils/config.js';
|
|
3
|
+
import { encryptAndSave } from '../utils/keystore.js';
|
|
4
|
+
import { heading, success, info, keyValue } from '../utils/output.js';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
export async function initCommand() {
|
|
7
|
+
heading('Welcome to Crumb');
|
|
8
|
+
if (configExists()) {
|
|
9
|
+
info(`Config already exists at ${getConfigPath()}`);
|
|
10
|
+
const { overwrite } = await inquirer.prompt([
|
|
11
|
+
{
|
|
12
|
+
type: 'confirm',
|
|
13
|
+
name: 'overwrite',
|
|
14
|
+
message: 'Overwrite existing config?',
|
|
15
|
+
default: false,
|
|
16
|
+
},
|
|
17
|
+
]);
|
|
18
|
+
if (!overwrite) {
|
|
19
|
+
info('Aborted.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
info(`Creating config at ${getConfigPath()}`);
|
|
24
|
+
console.log();
|
|
25
|
+
const { chain } = await inquirer.prompt([
|
|
26
|
+
{
|
|
27
|
+
type: 'list',
|
|
28
|
+
name: 'chain',
|
|
29
|
+
message: 'Select chain:',
|
|
30
|
+
choices: [
|
|
31
|
+
{ name: 'Arc Testnet', value: 'arcTestnet' },
|
|
32
|
+
],
|
|
33
|
+
default: 'arcTestnet',
|
|
34
|
+
},
|
|
35
|
+
]);
|
|
36
|
+
const { generateWallet } = await inquirer.prompt([
|
|
37
|
+
{
|
|
38
|
+
type: 'confirm',
|
|
39
|
+
name: 'generateWallet',
|
|
40
|
+
message: 'Generate a new wallet?',
|
|
41
|
+
default: true,
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
if (generateWallet) {
|
|
45
|
+
const wallet = createWallet();
|
|
46
|
+
const { password } = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'password',
|
|
49
|
+
name: 'password',
|
|
50
|
+
message: 'Set a keystore password:',
|
|
51
|
+
mask: '*',
|
|
52
|
+
},
|
|
53
|
+
]);
|
|
54
|
+
encryptAndSave(wallet.privateKey, password);
|
|
55
|
+
writeConfig({
|
|
56
|
+
activeWallet: wallet.address,
|
|
57
|
+
chain,
|
|
58
|
+
});
|
|
59
|
+
console.log();
|
|
60
|
+
success('Wallet created');
|
|
61
|
+
keyValue('Address:', wallet.address);
|
|
62
|
+
keyValue('Chain:', chain);
|
|
63
|
+
keyValue('Saved to:', '~/.crumb/keystore.enc (AES-256-GCM, password-protected)');
|
|
64
|
+
console.log();
|
|
65
|
+
info('Next steps:');
|
|
66
|
+
info(' 1. Fund your wallet with testnet USDC');
|
|
67
|
+
info(' 2. Deposit into Gateway: npx crumb deposit <amount>');
|
|
68
|
+
info(' 3. Start paying: npx crumb pay <url>');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
writeConfig({ chain });
|
|
72
|
+
success('Config created');
|
|
73
|
+
info('Run `npx crumb wallet create` to create a wallet later.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,QAAQ,MAAM,UAAU,CAAA;AAE/B,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAE3B,IAAI,YAAY,EAAE,EAAE,CAAC;QACnB,IAAI,CAAC,4BAA4B,aAAa,EAAE,EAAE,CAAC,CAAA;QAEnD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YAC1C;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,4BAA4B;gBACrC,OAAO,EAAE,KAAK;aACf;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,CAAA;YAChB,OAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,CAAC,sBAAsB,aAAa,EAAE,EAAE,CAAC,CAAA;IAC7C,OAAO,CAAC,GAAG,EAAE,CAAA;IAEb,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACtC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE;aAC7C;YACD,OAAO,EAAE,YAAY;SACtB;KACF,CAAC,CAAA;IAEF,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAC/C;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE,IAAI;SACd;KACF,CAAC,CAAA;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAA;QAE7B,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YACzC;gBACE,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,0BAA0B;gBACnC,IAAI,EAAE,GAAG;aACV;SACF,CAAC,CAAA;QAEF,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QAE3C,WAAW,CAAC;YACV,YAAY,EAAE,MAAM,CAAC,OAAO;YAC5B,KAAK;SACN,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,gBAAgB,CAAC,CAAA;QACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACpC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACzB,QAAQ,CAAC,WAAW,EAAE,yDAAyD,CAAC,CAAA;QAChF,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,IAAI,CAAC,aAAa,CAAC,CAAA;QACnB,IAAI,CAAC,yCAAyC,CAAC,CAAA;QAC/C,IAAI,CAAC,uDAAuD,CAAC,CAAA;QAC7D,IAAI,CAAC,wCAAwC,CAAC,CAAA;IAChD,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QACtB,OAAO,CAAC,gBAAgB,CAAC,CAAA;QACzB,IAAI,CAAC,yDAAyD,CAAC,CAAA;IACjE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pay.d.ts","sourceRoot":"","sources":["../../src/commands/pay.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+C7F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { GatewayClient } from 'crumb-alpha-core';
|
|
2
|
+
import { readConfig } from '../utils/config.js';
|
|
3
|
+
import { loadPrivateKey, getPassword } from '../utils/keystore.js';
|
|
4
|
+
import { heading, success, error, info, keyValue } from '../utils/output.js';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
export async function payCommand(url, options) {
|
|
7
|
+
heading('Pay');
|
|
8
|
+
const config = readConfig();
|
|
9
|
+
if (!config.activeWallet) {
|
|
10
|
+
error('No wallet configured. Run `crumb init` first.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let password;
|
|
14
|
+
try {
|
|
15
|
+
password = getPassword();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
error('No password provided. Set CRUMB_KEYSTORE_PASSWORD env var.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let privateKey;
|
|
22
|
+
try {
|
|
23
|
+
privateKey = loadPrivateKey(password);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
error(`Failed to decrypt keystore: ${err.message}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const chain = (config.chain ?? 'arcTestnet');
|
|
30
|
+
const gateway = new GatewayClient({
|
|
31
|
+
chain,
|
|
32
|
+
privateKey: privateKey,
|
|
33
|
+
});
|
|
34
|
+
info(`Paying for ${url}...`);
|
|
35
|
+
const spinner = ora(' Processing payment...').start();
|
|
36
|
+
try {
|
|
37
|
+
const result = await gateway.pay(url);
|
|
38
|
+
spinner.stop();
|
|
39
|
+
console.log();
|
|
40
|
+
success('Payment complete');
|
|
41
|
+
keyValue('Amount:', `${result.formattedAmount} USDC`);
|
|
42
|
+
keyValue('Tx:', result.transaction);
|
|
43
|
+
keyValue('Status:', result.status.toString());
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
spinner.stop();
|
|
47
|
+
error(`Payment failed: ${err.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=pay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pay.js","sourceRoot":"","sources":["../../src/commands/pay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,OAAgC;IAC5E,OAAO,CAAC,KAAK,CAAC,CAAA;IAEd,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACtD,OAAM;IACR,CAAC;IAED,IAAI,QAAgB,CAAA;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,4DAA4D,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IAED,IAAI,UAAkB,CAAA;IACtB,IAAI,CAAC;QACH,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,YAAY,CAAuB,CAAA;IAClE,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,KAAK;QACL,UAAU,EAAE,UAA2B;KACxC,CAAC,CAAA;IAEF,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,CAAA;IAC5B,MAAM,OAAO,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAA;IAEtD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACrC,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,kBAAkB,CAAC,CAAA;QAC3B,QAAQ,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,eAAe,OAAO,CAAC,CAAA;QACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;QACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC/C,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,KAAK,CAAC,mBAAmB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAGA,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readConfig } from '../utils/config.js';
|
|
2
|
+
import { heading, success, error, info, keyValue } from '../utils/output.js';
|
|
3
|
+
export async function serveCommand(file, options) {
|
|
4
|
+
heading('Crumb Provider');
|
|
5
|
+
const config = readConfig();
|
|
6
|
+
if (!config.activeWallet) {
|
|
7
|
+
error('No wallet configured. Run `crumb init` first.');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const port = parseInt(options.port ?? '3000', 10);
|
|
11
|
+
const price = options.price ?? '$0.01';
|
|
12
|
+
try {
|
|
13
|
+
const express = (await import('express')).default;
|
|
14
|
+
const { createGatewayMiddleware } = await import('@circle-fin/x402-batching/server');
|
|
15
|
+
const handler = await import(file);
|
|
16
|
+
const userHandler = handler.default ?? handler;
|
|
17
|
+
const app = express();
|
|
18
|
+
app.use(express.json());
|
|
19
|
+
const gateway = createGatewayMiddleware({
|
|
20
|
+
sellerAddress: config.activeWallet,
|
|
21
|
+
description: `Local provider — ${price} per call`,
|
|
22
|
+
});
|
|
23
|
+
app.all('*', gateway.require(price), (req, res, next) => {
|
|
24
|
+
if (req.payment) {
|
|
25
|
+
success(`Payment received — ${req.payment.amount} USDC from ${req.payment.payer} (tx: ${req.payment.transaction?.slice(0, 8)}...)`);
|
|
26
|
+
}
|
|
27
|
+
next();
|
|
28
|
+
}, userHandler);
|
|
29
|
+
app.listen(port, () => {
|
|
30
|
+
keyValue('Endpoint:', `http://localhost:${port}`);
|
|
31
|
+
keyValue('Price:', `${price} per call`);
|
|
32
|
+
keyValue('Wallet:', config.activeWallet);
|
|
33
|
+
console.log();
|
|
34
|
+
info('Waiting for payments...');
|
|
35
|
+
console.log();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
error(`Failed to start server: ${err.message}`);
|
|
40
|
+
info('Make sure express is installed: pnpm add express');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE5E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,OAA0C;IAE1C,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAEzB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACtD,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAA;IAEtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAA;QACjD,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAA;QAEpF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAA;QAE9C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;QACrB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QAEvB,MAAM,OAAO,GAAG,uBAAuB,CAAC;YACtC,aAAa,EAAE,MAAM,CAAC,YAAY;YAClC,WAAW,EAAE,oBAAoB,KAAK,WAAW;SAClD,CAAC,CAAA;QAEF,GAAG,CAAC,GAAG,CACL,GAAG,EACH,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EACtB,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;YAChC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,OAAO,CAAC,sBAAsB,GAAG,CAAC,OAAO,CAAC,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;YACrI,CAAC;YACD,IAAI,EAAE,CAAA;QACR,CAAC,EACD,WAAW,CACZ,CAAA;QAED,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACpB,QAAQ,CAAC,WAAW,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAA;YACjD,QAAQ,CAAC,QAAQ,EAAE,GAAG,KAAK,WAAW,CAAC,CAAA;YACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,YAAa,CAAC,CAAA;YACzC,OAAO,CAAC,GAAG,EAAE,CAAA;YACb,IAAI,CAAC,yBAAyB,CAAC,CAAA;YAC/B,OAAO,CAAC,GAAG,EAAE,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/C,IAAI,CAAC,kDAAkD,CAAC,CAAA;IAC1D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAMA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuCzD;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYvD;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBvD"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createWallet } from 'crumb-alpha-core';
|
|
2
|
+
import { readConfig, writeConfig } from '../utils/config.js';
|
|
3
|
+
import { encryptAndSave, keystoreExists } from '../utils/keystore.js';
|
|
4
|
+
import { heading, success, info, keyValue, error } from '../utils/output.js';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
export async function walletCreateCommand() {
|
|
7
|
+
heading('Create Wallet');
|
|
8
|
+
if (keystoreExists()) {
|
|
9
|
+
const { overwrite } = await inquirer.prompt([
|
|
10
|
+
{
|
|
11
|
+
type: 'confirm',
|
|
12
|
+
name: 'overwrite',
|
|
13
|
+
message: 'A wallet already exists. Overwrite?',
|
|
14
|
+
default: false,
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
if (!overwrite) {
|
|
18
|
+
info('Aborted.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const wallet = createWallet();
|
|
23
|
+
const { password } = await inquirer.prompt([
|
|
24
|
+
{
|
|
25
|
+
type: 'password',
|
|
26
|
+
name: 'password',
|
|
27
|
+
message: 'Set a keystore password:',
|
|
28
|
+
mask: '*',
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
encryptAndSave(wallet.privateKey, password);
|
|
32
|
+
const config = readConfig();
|
|
33
|
+
config.activeWallet = wallet.address;
|
|
34
|
+
writeConfig(config);
|
|
35
|
+
console.log();
|
|
36
|
+
success('Wallet created');
|
|
37
|
+
keyValue('Address:', wallet.address);
|
|
38
|
+
keyValue('Saved to:', '~/.crumb/keystore.enc');
|
|
39
|
+
}
|
|
40
|
+
export async function walletShowCommand() {
|
|
41
|
+
heading('Wallet');
|
|
42
|
+
const config = readConfig();
|
|
43
|
+
if (!config.activeWallet) {
|
|
44
|
+
error('No wallet configured. Run `crumb wallet create` first.');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
keyValue('Address:', config.activeWallet);
|
|
48
|
+
keyValue('Chain:', config.chain);
|
|
49
|
+
keyValue('Keystore:', '~/.crumb/keystore.enc');
|
|
50
|
+
}
|
|
51
|
+
export async function walletFundCommand() {
|
|
52
|
+
heading('Fund Wallet');
|
|
53
|
+
const config = readConfig();
|
|
54
|
+
if (!config.activeWallet) {
|
|
55
|
+
error('No wallet configured. Run `crumb wallet create` first.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
info('To fund your wallet with testnet USDC:');
|
|
59
|
+
console.log();
|
|
60
|
+
keyValue('Address:', config.activeWallet);
|
|
61
|
+
keyValue('Chain:', config.chain);
|
|
62
|
+
console.log();
|
|
63
|
+
info('1. Get testnet USDC from a faucet for your chain');
|
|
64
|
+
info('2. Send USDC to your address above');
|
|
65
|
+
info('3. Run `npx crumb deposit <amount>` to move USDC into Gateway');
|
|
66
|
+
console.log();
|
|
67
|
+
info('Once deposited, run `npx crumb balance` to check your balance.');
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withdraw.d.ts","sourceRoot":"","sources":["../../src/commands/withdraw.ts"],"names":[],"mappings":"AAOA,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { GatewayClient } from 'crumb-alpha-core';
|
|
2
|
+
import { readConfig } from '../utils/config.js';
|
|
3
|
+
import { loadPrivateKey, getPassword } from '../utils/keystore.js';
|
|
4
|
+
import { heading, success, error, info, keyValue } from '../utils/output.js';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
export async function withdrawCommand(amount, options) {
|
|
7
|
+
heading('Withdraw');
|
|
8
|
+
const config = readConfig();
|
|
9
|
+
if (!config.activeWallet) {
|
|
10
|
+
error('No wallet configured. Run `crumb init` first.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let password;
|
|
14
|
+
try {
|
|
15
|
+
password = getPassword();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
error('No password provided. Set CRUMB_KEYSTORE_PASSWORD env var.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let privateKey;
|
|
22
|
+
try {
|
|
23
|
+
privateKey = loadPrivateKey(password);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
error(`Failed to decrypt keystore: ${err.message}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const chain = (config.chain ?? 'arcTestnet');
|
|
30
|
+
const gateway = new GatewayClient({
|
|
31
|
+
chain,
|
|
32
|
+
privateKey: privateKey,
|
|
33
|
+
});
|
|
34
|
+
const destChain = options.chain;
|
|
35
|
+
info(`Withdrawing ${amount} USDC from Gateway${destChain ? ` to ${destChain}` : ''}...`);
|
|
36
|
+
const spinner = ora(' Processing withdrawal...').start();
|
|
37
|
+
try {
|
|
38
|
+
const result = await gateway.withdraw(amount, {
|
|
39
|
+
chain: destChain,
|
|
40
|
+
});
|
|
41
|
+
spinner.stop();
|
|
42
|
+
console.log();
|
|
43
|
+
success('Withdrawn');
|
|
44
|
+
keyValue('Amount:', `${result.formattedAmount} USDC`);
|
|
45
|
+
keyValue('Tx:', result.mintTxHash);
|
|
46
|
+
keyValue('From:', result.sourceChain);
|
|
47
|
+
keyValue('To:', result.destinationChain);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
spinner.stop();
|
|
51
|
+
error(`Withdrawal failed: ${err.message}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=withdraw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withdraw.js","sourceRoot":"","sources":["../../src/commands/withdraw.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,OAA2B;IAE3B,OAAO,CAAC,UAAU,CAAC,CAAA;IAEnB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACtD,OAAM;IACR,CAAC;IAED,IAAI,QAAgB,CAAA;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,4DAA4D,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IAED,IAAI,UAAkB,CAAA;IACtB,IAAI,CAAC;QACH,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,+BAA+B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,YAAY,CAAuB,CAAA;IAClE,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,KAAK;QACL,UAAU,EAAE,UAA2B;KACxC,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,OAAO,CAAC,KAAuC,CAAA;IACjE,IAAI,CAAC,eAAe,MAAM,qBAAqB,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAA;IAEzD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC5C,KAAK,EAAE,SAAS;SACjB,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,WAAW,CAAC,CAAA;QACpB,QAAQ,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,eAAe,OAAO,CAAC,CAAA;QACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;QAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;QACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;IAC1C,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,KAAK,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { initCommand } from './commands/init.js';
|
|
4
|
+
import { walletCreateCommand, walletShowCommand, walletFundCommand } from './commands/wallet.js';
|
|
5
|
+
import { balanceCommand } from './commands/balance.js';
|
|
6
|
+
import { depositCommand } from './commands/deposit.js';
|
|
7
|
+
import { withdrawCommand } from './commands/withdraw.js';
|
|
8
|
+
import { payCommand } from './commands/pay.js';
|
|
9
|
+
import { historyCommand } from './commands/history.js';
|
|
10
|
+
import { serveCommand } from './commands/serve.js';
|
|
11
|
+
const program = new Command();
|
|
12
|
+
program
|
|
13
|
+
.name('crumb')
|
|
14
|
+
.description('CLI for Crumb agentic payments via Circle Gateway')
|
|
15
|
+
.version('0.1.0');
|
|
16
|
+
program
|
|
17
|
+
.command('init')
|
|
18
|
+
.description('Initialize Crumb — create config and wallet')
|
|
19
|
+
.action(initCommand);
|
|
20
|
+
const wallet = program
|
|
21
|
+
.command('wallet')
|
|
22
|
+
.description('Wallet management');
|
|
23
|
+
wallet
|
|
24
|
+
.command('create')
|
|
25
|
+
.description('Create a new wallet')
|
|
26
|
+
.action(walletCreateCommand);
|
|
27
|
+
wallet
|
|
28
|
+
.command('show')
|
|
29
|
+
.description('Show active wallet info')
|
|
30
|
+
.action(walletShowCommand);
|
|
31
|
+
wallet
|
|
32
|
+
.command('fund')
|
|
33
|
+
.description('Instructions to fund your wallet')
|
|
34
|
+
.action(walletFundCommand);
|
|
35
|
+
program
|
|
36
|
+
.command('balance')
|
|
37
|
+
.description('Check USDC balance (wallet + gateway)')
|
|
38
|
+
.action(balanceCommand);
|
|
39
|
+
program
|
|
40
|
+
.command('deposit')
|
|
41
|
+
.description('Deposit USDC into Gateway for gasless payments')
|
|
42
|
+
.argument('<amount>', 'Amount in USDC (e.g. 10.0)')
|
|
43
|
+
.action(depositCommand);
|
|
44
|
+
program
|
|
45
|
+
.command('withdraw')
|
|
46
|
+
.description('Withdraw USDC from Gateway')
|
|
47
|
+
.argument('<amount>', 'Amount in USDC (e.g. 10.0)')
|
|
48
|
+
.option('--chain <chain>', 'Destination chain (for cross-chain withdrawal)')
|
|
49
|
+
.action(withdrawCommand);
|
|
50
|
+
program
|
|
51
|
+
.command('pay')
|
|
52
|
+
.description('Pay for an x402-protected resource')
|
|
53
|
+
.argument('<url>', 'URL of the x402-protected resource')
|
|
54
|
+
.option('--max-payment <amount>', 'Maximum USDC willing to pay')
|
|
55
|
+
.action(payCommand);
|
|
56
|
+
program
|
|
57
|
+
.command('history')
|
|
58
|
+
.description('View transaction history')
|
|
59
|
+
.option('--limit <n>', 'Number of transactions to show', '20')
|
|
60
|
+
.action((options) => historyCommand({ limit: parseInt(options.limit, 10) }));
|
|
61
|
+
program
|
|
62
|
+
.command('serve')
|
|
63
|
+
.description('Run a local test provider')
|
|
64
|
+
.argument('<file>', 'Path to handler file')
|
|
65
|
+
.option('--port <port>', 'Port to listen on', '3000')
|
|
66
|
+
.option('--price <price>', 'USDC per call (e.g. $0.01)', '$0.01')
|
|
67
|
+
.action(serveCommand);
|
|
68
|
+
program.parse();
|
|
69
|
+
//# sourceMappingURL=index.js.map
|