@thirdfy/agent-cli 0.1.31 → 0.1.33
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/CHANGELOG.md +21 -0
- package/bin/thirdfy-agent.mjs +109 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.33] - 2026-05-12
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Bitfinex CEX delegation:** Permission profiles for funding vs spot, `--permission-profile` on credential upsert, onboarding hints when credentials are missing from Thirdfy delegation context, and `get-bitfinex-ledgers-hist` read-check documentation.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **DogeOS provider discovery:** Tests and docs aligned with catalog-driven provider hints.
|
|
16
|
+
|
|
17
|
+
## [0.1.32] - 2026-05-08
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **Earn partners (Vaults.fyi and Yield.xyz):** `thirdfy-agent actions --provider vaults-fyi|yield-xyz` returns catalog-aligned hints (`get_vaults_fyi_vaults` / `get_yield_xyz_opportunities`, generic Earn reads, `deposit_earn_position` / `withdraw_earn_position`). Provider inference and `--provider earn` filtering include these providers alongside Morpho and Curve.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Public docs (`docs/command-reference.md`, `docs/action-inventory-and-compatibility.md`, `docs/providers/index.md`) describe partner earn discovery and transaction-prep-first writes.
|
|
26
|
+
- **`--provider earn` hints:** Umbrella `readActions` lists Morpho and Curve discovery actions (`get_morpho_vaults`, `get_curve_pools`) together with partner reads so Earn hints stay symmetric across sub-providers.
|
|
27
|
+
|
|
7
28
|
## [0.1.31] - 2026-05-07
|
|
8
29
|
|
|
9
30
|
### Fixed
|
package/bin/thirdfy-agent.mjs
CHANGED
|
@@ -19,9 +19,23 @@ const DEFAULT_API_BASE = 'https://api.thirdfy.com';
|
|
|
19
19
|
const DEFAULT_TIMEOUT_MS = 30000;
|
|
20
20
|
const DEFAULT_CATALOG_CACHE_TTL_MS = 60_000;
|
|
21
21
|
const DEFAULT_BITFINEX_BASE_URL = 'https://api.bitfinex.com';
|
|
22
|
-
const
|
|
23
|
-
funding: {
|
|
24
|
-
|
|
22
|
+
const BITFINEX_PERMISSION_PROFILES = {
|
|
23
|
+
funding: {
|
|
24
|
+
id: 'funding',
|
|
25
|
+
credentialRef: 'bitfinex:funding-primary',
|
|
26
|
+
required: {
|
|
27
|
+
funding: { read: 1, write: 1 },
|
|
28
|
+
wallets: { read: 1, write: 0 },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
spot: {
|
|
32
|
+
id: 'spot',
|
|
33
|
+
credentialRef: 'bitfinex:spot-primary',
|
|
34
|
+
required: {
|
|
35
|
+
orders: { read: 1, write: 1 },
|
|
36
|
+
wallets: { read: 1, write: 0 },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
25
39
|
};
|
|
26
40
|
const RUN_MODES = ['thirdfy', 'self', 'hybrid', 'agent_wallet'];
|
|
27
41
|
const HYBRID_WALLET_MODES = ['self', 'agent_wallet'];
|
|
@@ -79,15 +93,21 @@ main().catch((error) => {
|
|
|
79
93
|
|
|
80
94
|
function buildTopLevelOnboardingHint(payload) {
|
|
81
95
|
const reason = String(payload?.blockedReason || payload?.error || '').trim();
|
|
96
|
+
const permissionProfile = inferBitfinexPermissionProfileFromAction(
|
|
97
|
+
payload?.resolvedAction || payload?.action || payload?.requestedAction
|
|
98
|
+
);
|
|
82
99
|
if (!reason) return null;
|
|
83
100
|
if (
|
|
84
|
-
[
|
|
85
|
-
|
|
86
|
-
|
|
101
|
+
[
|
|
102
|
+
'CEX_CREDENTIAL_NOT_FOUND',
|
|
103
|
+
'BITFINEX_CREDENTIALS_NOT_IN_CONTEXT',
|
|
104
|
+
'BITFINEX_CREDENTIALS_NOT_IN_THIRDFY_DELEGATION_CONTEXT',
|
|
105
|
+
'BITFINEX_ENV_CREDENTIALS_NOT_CONFIGURED',
|
|
106
|
+
].includes(reason)
|
|
87
107
|
) {
|
|
88
108
|
return {
|
|
89
109
|
type: 'bitfinex_credentials',
|
|
90
|
-
command: buildBitfinexOnboardingCommand(),
|
|
110
|
+
command: buildBitfinexOnboardingCommand(permissionProfile),
|
|
91
111
|
};
|
|
92
112
|
}
|
|
93
113
|
return null;
|
|
@@ -530,10 +550,18 @@ function getTradingProviderHint(providerId) {
|
|
|
530
550
|
category: 'earn',
|
|
531
551
|
canonicalReadAction: 'get_earn_opportunities',
|
|
532
552
|
canonicalWriteAction: 'deposit_earn_position',
|
|
533
|
-
readActions: [
|
|
553
|
+
readActions: [
|
|
554
|
+
'get_earn_opportunities',
|
|
555
|
+
'get_earn_provider',
|
|
556
|
+
'get_earn_position',
|
|
557
|
+
'get_morpho_vaults',
|
|
558
|
+
'get_curve_pools',
|
|
559
|
+
'get_vaults_fyi_vaults',
|
|
560
|
+
'get_yield_xyz_opportunities',
|
|
561
|
+
],
|
|
534
562
|
orderManagementActions: ['deposit_earn_position', 'withdraw_earn_position'],
|
|
535
563
|
laneCompatibility:
|
|
536
|
-
'Generic earn writes use deposit_earn_position / withdraw_earn_position on normal Thirdfy policy/delegation rails; routing selects Morpho
|
|
564
|
+
'Generic earn writes use deposit_earn_position / withdraw_earn_position on normal Thirdfy policy/delegation rails; routing selects Morpho, Curve, Vaults.fyi, or Yield.xyz adapters per provider/opportunity.',
|
|
537
565
|
};
|
|
538
566
|
}
|
|
539
567
|
if (provider === 'morpho') {
|
|
@@ -563,6 +591,34 @@ function getTradingProviderHint(providerId) {
|
|
|
563
591
|
'Curve EVM writes are limited to the validated Base mainnet 4pool adapter; other pools remain discovery-only until per-pool calldata is validated.',
|
|
564
592
|
};
|
|
565
593
|
}
|
|
594
|
+
if (provider === 'vaults-fyi') {
|
|
595
|
+
return {
|
|
596
|
+
provider,
|
|
597
|
+
category: 'earn',
|
|
598
|
+
canonicalReadAction: 'get_vaults_fyi_vaults',
|
|
599
|
+
canonicalWriteAction: 'deposit_earn_position',
|
|
600
|
+
readActions: ['get_vaults_fyi_vaults', 'get_earn_opportunities', 'get_earn_provider', 'get_earn_position'],
|
|
601
|
+
orderManagementActions: ['deposit_earn_position', 'withdraw_earn_position'],
|
|
602
|
+
laneCompatibility:
|
|
603
|
+
'Vaults.fyi writes are transaction-prep first. Thirdfy validates partner payloads, chain/user context, and allowed targets before returning or submitting prepared calls.',
|
|
604
|
+
example:
|
|
605
|
+
'thirdfy-agent actions --provider vaults-fyi && thirdfy-agent preflight --action deposit_earn_position --params \'{"providerId":"vaults-fyi","opportunityId":"...","vaultAddress":"0x...","tokenAddress":"0x...","amount":"10","chainId":8453}\'',
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
if (provider === 'yield-xyz') {
|
|
609
|
+
return {
|
|
610
|
+
provider,
|
|
611
|
+
category: 'earn',
|
|
612
|
+
canonicalReadAction: 'get_yield_xyz_opportunities',
|
|
613
|
+
canonicalWriteAction: 'deposit_earn_position',
|
|
614
|
+
readActions: ['get_yield_xyz_opportunities', 'get_earn_opportunities', 'get_earn_provider', 'get_earn_position'],
|
|
615
|
+
orderManagementActions: ['deposit_earn_position', 'withdraw_earn_position'],
|
|
616
|
+
laneCompatibility:
|
|
617
|
+
'Yield.xyz writes are transaction-prep first. Thirdfy calls Yield.xyz directly and validates returned unsigned transactions with @yieldxyz/shield before signing or returning prepared calls.',
|
|
618
|
+
example:
|
|
619
|
+
'thirdfy-agent actions --provider yield-xyz && thirdfy-agent preflight --action deposit_earn_position --params \'{"providerId":"yield-xyz","opportunityId":"ethereum-eth-lido-staking","tokenAddress":"0x...","amount":"0.01","chainId":1}\'',
|
|
620
|
+
};
|
|
621
|
+
}
|
|
566
622
|
return null;
|
|
567
623
|
}
|
|
568
624
|
|
|
@@ -582,11 +638,15 @@ function getCachedProviderHintFromCapabilities(provider) {
|
|
|
582
638
|
earn: 'deposit_earn_position',
|
|
583
639
|
morpho: 'deposit_earn_position',
|
|
584
640
|
curve: 'deposit_earn_position',
|
|
641
|
+
'vaults-fyi': 'deposit_earn_position',
|
|
642
|
+
'yield-xyz': 'deposit_earn_position',
|
|
585
643
|
};
|
|
586
644
|
const canonicalReadActions = {
|
|
587
645
|
earn: 'get_earn_opportunities',
|
|
588
646
|
morpho: 'get_morpho_vaults',
|
|
589
647
|
curve: 'get_curve_pools',
|
|
648
|
+
'vaults-fyi': 'get_vaults_fyi_vaults',
|
|
649
|
+
'yield-xyz': 'get_yield_xyz_opportunities',
|
|
590
650
|
prediction: 'get_prediction_markets',
|
|
591
651
|
};
|
|
592
652
|
return {
|
|
@@ -1565,12 +1625,17 @@ async function commandDelegationRedeem(ctx, flags, capabilities) {
|
|
|
1565
1625
|
async function commandCredentialsUpsert(ctx, flags, capabilities) {
|
|
1566
1626
|
const authToken = getAuthToken(flags, 'Missing --auth-token (or THIRDFY_AUTH_TOKEN) for credentials upsert');
|
|
1567
1627
|
const venue = requireFlag(flags, 'venue', 'Missing --venue');
|
|
1628
|
+
const permissionProfile = String(flags.permissionProfile || 'funding').trim().toLowerCase();
|
|
1629
|
+
const bitfinexProfile =
|
|
1630
|
+
String(venue).trim().toLowerCase() === 'bitfinex'
|
|
1631
|
+
? BITFINEX_PERMISSION_PROFILES[permissionProfile] || BITFINEX_PERMISSION_PROFILES.funding
|
|
1632
|
+
: null;
|
|
1568
1633
|
const payload = {
|
|
1569
1634
|
venue,
|
|
1570
1635
|
apiKey: requireFlag(flags, 'apiKey', 'Missing --api-key'),
|
|
1571
1636
|
apiSecret: requireFlag(flags, 'apiSecret', 'Missing --api-secret'),
|
|
1572
1637
|
credentialType: String(flags.credentialType || 'api_key'),
|
|
1573
|
-
credentialRef: String(flags.credentialRef || ''),
|
|
1638
|
+
credentialRef: String(flags.credentialRef || bitfinexProfile?.credentialRef || ''),
|
|
1574
1639
|
};
|
|
1575
1640
|
if (flags.passphrase) payload.passphrase = String(flags.passphrase);
|
|
1576
1641
|
if (flags.metadata) payload.metadata = parseJsonFlag(flags, 'metadata');
|
|
@@ -1586,6 +1651,7 @@ async function commandCredentialsUpsert(ctx, flags, capabilities) {
|
|
|
1586
1651
|
permissionProbe = await probeBitfinexPermissions({
|
|
1587
1652
|
apiKey: payload.apiKey,
|
|
1588
1653
|
apiSecret: payload.apiSecret,
|
|
1654
|
+
permissionProfile: bitfinexProfile?.id || 'funding',
|
|
1589
1655
|
timeoutMs: ctx.timeoutMs,
|
|
1590
1656
|
baseUrl: String(flags.bitfinexBaseUrl || process.env.BITFINEX_BASE_URL || DEFAULT_BITFINEX_BASE_URL),
|
|
1591
1657
|
});
|
|
@@ -2681,11 +2747,14 @@ function shouldUseBuildTxExecution(runMode, resolved) {
|
|
|
2681
2747
|
return true;
|
|
2682
2748
|
}
|
|
2683
2749
|
|
|
2684
|
-
function buildBitfinexOnboardingCommand() {
|
|
2750
|
+
function buildBitfinexOnboardingCommand(permissionProfile = 'funding') {
|
|
2751
|
+
const profile = BITFINEX_PERMISSION_PROFILES[permissionProfile] || BITFINEX_PERMISSION_PROFILES.funding;
|
|
2685
2752
|
return [
|
|
2686
2753
|
'thirdfy-agent credentials upsert',
|
|
2687
2754
|
'--auth-token "$THIRDFY_AUTH_TOKEN"',
|
|
2688
2755
|
'--venue bitfinex',
|
|
2756
|
+
`--permission-profile ${profile.id}`,
|
|
2757
|
+
`--credential-ref ${profile.credentialRef}`,
|
|
2689
2758
|
'--api-key "<BITFINEX_API_KEY>"',
|
|
2690
2759
|
'--api-secret "<BITFINEX_API_SECRET>"',
|
|
2691
2760
|
'--verify-permissions',
|
|
@@ -2693,6 +2762,15 @@ function buildBitfinexOnboardingCommand() {
|
|
|
2693
2762
|
].join(' ');
|
|
2694
2763
|
}
|
|
2695
2764
|
|
|
2765
|
+
function inferBitfinexPermissionProfileFromAction(actionName) {
|
|
2766
|
+
const action = String(actionName || '')
|
|
2767
|
+
.trim()
|
|
2768
|
+
.toLowerCase()
|
|
2769
|
+
.replace(/[_\s]+/g, '-');
|
|
2770
|
+
if (!action.includes('bitfinex')) return 'funding';
|
|
2771
|
+
return action.includes('bitfinex-order') ? 'spot' : 'funding';
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2696
2774
|
function applyExecutionFallbackHints(normalized, { flags, runMode, resolvedAction }) {
|
|
2697
2775
|
if (!normalized || typeof normalized !== 'object') return normalized;
|
|
2698
2776
|
const next = { ...normalized };
|
|
@@ -2705,9 +2783,11 @@ function applyExecutionFallbackHints(normalized, { flags, runMode, resolvedActio
|
|
|
2705
2783
|
}
|
|
2706
2784
|
const resolvedActionLower = String(resolvedAction || '').trim().toLowerCase();
|
|
2707
2785
|
const looksBitfinexAction = resolvedActionLower.includes('bitfinex');
|
|
2786
|
+
const permissionProfile = inferBitfinexPermissionProfileFromAction(resolvedActionLower);
|
|
2708
2787
|
const cexCredentialMissingSignals = new Set([
|
|
2709
2788
|
'CEX_CREDENTIAL_NOT_FOUND',
|
|
2710
2789
|
'BITFINEX_CREDENTIALS_NOT_IN_CONTEXT',
|
|
2790
|
+
'BITFINEX_CREDENTIALS_NOT_IN_THIRDFY_DELEGATION_CONTEXT',
|
|
2711
2791
|
'BITFINEX_ENV_CREDENTIALS_NOT_CONFIGURED',
|
|
2712
2792
|
]);
|
|
2713
2793
|
const hasMissingCredentialSignal = Array.from(reasons).some((code) => cexCredentialMissingSignals.has(code));
|
|
@@ -2716,7 +2796,7 @@ function applyExecutionFallbackHints(normalized, { flags, runMode, resolvedActio
|
|
|
2716
2796
|
type: 'bitfinex_credentials',
|
|
2717
2797
|
message:
|
|
2718
2798
|
'Bitfinex credentials are missing for this delegated account. Onboard credentials first, then retry the same command.',
|
|
2719
|
-
command: buildBitfinexOnboardingCommand(),
|
|
2799
|
+
command: buildBitfinexOnboardingCommand(permissionProfile),
|
|
2720
2800
|
};
|
|
2721
2801
|
}
|
|
2722
2802
|
if (
|
|
@@ -3434,6 +3514,9 @@ function inferActionProvider(action) {
|
|
|
3434
3514
|
'get-curve-pool-details': 'curve',
|
|
3435
3515
|
'deposit-curve-pool': 'curve',
|
|
3436
3516
|
'withdraw-curve-pool': 'curve',
|
|
3517
|
+
'get-vaults-fyi-vaults': 'vaults-fyi',
|
|
3518
|
+
'get-vaults-fyi-opportunities': 'vaults-fyi',
|
|
3519
|
+
'get-yield-xyz-opportunities': 'yield-xyz',
|
|
3437
3520
|
'get-prediction-markets': 'polymarket',
|
|
3438
3521
|
'get-prediction-market': 'polymarket',
|
|
3439
3522
|
'get-prediction-order-book': 'polymarket',
|
|
@@ -3449,9 +3532,11 @@ function inferActionProvider(action) {
|
|
|
3449
3532
|
if (knownMap[key]) return knownMap[key];
|
|
3450
3533
|
if (key.includes('hyperliquid')) return 'hyperliquid';
|
|
3451
3534
|
if (key.includes('polymarket') || key.includes('prediction')) return 'polymarket';
|
|
3535
|
+
if (key.includes('vaults-fyi')) return 'vaults-fyi';
|
|
3536
|
+
if (key.includes('yield-xyz')) return 'yield-xyz';
|
|
3452
3537
|
if (key.includes('morpho')) return 'morpho';
|
|
3453
3538
|
if (key.includes('curve')) return 'curve';
|
|
3454
|
-
if (key.includes('earn')) return 'earn';
|
|
3539
|
+
if (key.includes('earn') || key.includes('yield') || key.includes('vault')) return 'earn';
|
|
3455
3540
|
if (key.includes('bridge')) return 'bridge';
|
|
3456
3541
|
if (key.includes('dogeos-barkswap')) return 'dogeos-barkswap';
|
|
3457
3542
|
if (key.includes('dogeos-laika')) return 'dogeos-laika';
|
|
@@ -3500,9 +3585,9 @@ function actionMatchesProvider(action, requestedProvider, allActions) {
|
|
|
3500
3585
|
if (requestedProvider === 'bridge') return isProviderActionKey(action, 'bridge');
|
|
3501
3586
|
if (requestedProvider.startsWith('dogeos')) return isProviderActionKey(action, requestedProvider);
|
|
3502
3587
|
if (requestedProvider === 'earn') {
|
|
3503
|
-
return provider === 'earn' || provider === 'morpho' || provider === 'curve' || isEarnCatalogAction(action);
|
|
3588
|
+
return provider === 'earn' || provider === 'morpho' || provider === 'curve' || provider === 'vaults-fyi' || provider === 'yield-xyz' || isEarnCatalogAction(action);
|
|
3504
3589
|
}
|
|
3505
|
-
if (requestedProvider === 'morpho' || requestedProvider === 'curve') {
|
|
3590
|
+
if (requestedProvider === 'morpho' || requestedProvider === 'curve' || requestedProvider === 'vaults-fyi' || requestedProvider === 'yield-xyz') {
|
|
3506
3591
|
const hasProtocolSpecificEarnRows = allActions.some((candidate) => getActionProviderWithInference(candidate) === requestedProvider);
|
|
3507
3592
|
return isProviderActionKey(action, requestedProvider) || (!hasProtocolSpecificEarnRows && isEarnCatalogAction(action));
|
|
3508
3593
|
}
|
|
@@ -4015,9 +4100,10 @@ function parseBitfinexPermissionRows(rawData) {
|
|
|
4015
4100
|
return parsed;
|
|
4016
4101
|
}
|
|
4017
4102
|
|
|
4018
|
-
function getMissingBitfinexScopes(scopePermissions) {
|
|
4103
|
+
function getMissingBitfinexScopes(scopePermissions, permissionProfile = 'funding') {
|
|
4104
|
+
const profile = BITFINEX_PERMISSION_PROFILES[permissionProfile] || BITFINEX_PERMISSION_PROFILES.funding;
|
|
4019
4105
|
const missing = [];
|
|
4020
|
-
for (const [scope, required] of Object.entries(
|
|
4106
|
+
for (const [scope, required] of Object.entries(profile.required)) {
|
|
4021
4107
|
const actual = scopePermissions[scope] || { read: 0, write: 0 };
|
|
4022
4108
|
if (actual.read < required.read || actual.write < required.write) {
|
|
4023
4109
|
missing.push({
|
|
@@ -4030,7 +4116,7 @@ function getMissingBitfinexScopes(scopePermissions) {
|
|
|
4030
4116
|
return missing;
|
|
4031
4117
|
}
|
|
4032
4118
|
|
|
4033
|
-
async function probeBitfinexPermissions({ apiKey, apiSecret, timeoutMs, baseUrl }) {
|
|
4119
|
+
async function probeBitfinexPermissions({ apiKey, apiSecret, permissionProfile = 'funding', timeoutMs, baseUrl }) {
|
|
4034
4120
|
const normalizedBaseUrl = String(baseUrl || DEFAULT_BITFINEX_BASE_URL).trim().replace(/\/+$/, '');
|
|
4035
4121
|
const apiPath = '/v2/auth/r/permissions';
|
|
4036
4122
|
const nonce = Date.now().toString();
|
|
@@ -4081,18 +4167,19 @@ async function probeBitfinexPermissions({ apiKey, apiSecret, timeoutMs, baseUrl
|
|
|
4081
4167
|
);
|
|
4082
4168
|
}
|
|
4083
4169
|
const scopePermissions = parseBitfinexPermissionRows(parsed);
|
|
4084
|
-
const missingScopes = getMissingBitfinexScopes(scopePermissions);
|
|
4170
|
+
const missingScopes = getMissingBitfinexScopes(scopePermissions, permissionProfile);
|
|
4085
4171
|
if (missingScopes.length > 0) {
|
|
4086
4172
|
throw createCliError(
|
|
4087
4173
|
'BITFINEX_PERMISSION_SCOPE_MISSING',
|
|
4088
4174
|
`Bitfinex key is missing required scopes (${missingScopes
|
|
4089
4175
|
.map((entry) => entry.scope)
|
|
4090
|
-
.join(', ')}). Enable
|
|
4091
|
-
{ missingScopes, scopePermissions }
|
|
4176
|
+
.join(', ')}). Enable the ${permissionProfile} profile scopes and retry onboarding.`,
|
|
4177
|
+
{ missingScopes, scopePermissions, permissionProfile }
|
|
4092
4178
|
);
|
|
4093
4179
|
}
|
|
4094
4180
|
return {
|
|
4095
4181
|
venue: 'bitfinex',
|
|
4182
|
+
permissionProfile,
|
|
4096
4183
|
checked: true,
|
|
4097
4184
|
scopes: scopePermissions,
|
|
4098
4185
|
missingScopes: [],
|
|
@@ -4156,7 +4243,7 @@ Core commands:
|
|
|
4156
4243
|
thirdfy-agent wallet sign --agent-api-key <key> --action <id> --params <json> [--chain-id <id>] [--json]
|
|
4157
4244
|
thirdfy-agent wallet submit --signed-tx-hex <hex> [--chain-id <id>] [--rpc-url <url>] [--json]
|
|
4158
4245
|
thirdfy-agent agent run --agent-api-key <key> --action <id> --params <json> [--signer-method managed_wallet_server|byow|fanout_intent] [--strategy-intent single_wallet|fanout] [--run-mode <mode>] [--user-did <did>] [--json]
|
|
4159
|
-
thirdfy-agent credentials upsert --auth-token <token> --venue <id> --api-key <key> --api-secret <secret> [--verify-permissions] [--skip-permissions-probe] [--bitfinex-base-url <url>] [--json]
|
|
4246
|
+
thirdfy-agent credentials upsert --auth-token <token> --venue <id> --api-key <key> --api-secret <secret> [--permission-profile funding|spot] [--credential-ref <ref>] [--verify-permissions] [--skip-permissions-probe] [--bitfinex-base-url <url>] [--json]
|
|
4160
4247
|
thirdfy-agent credentials status --auth-token <token> [--venue <id>] [--json]
|
|
4161
4248
|
thirdfy-agent agent auth challenge --agent-key <key> [--wallet-address <addr>] [--chain-id <id>] [--json]
|
|
4162
4249
|
thirdfy-agent agent auth verify --challenge-id <id> --signature <hex> --agent-key <key> [--wallet-address <addr>] [--json]
|