Creator Center
/Tool/Salt
app icon

Salt

Verified by Dify
No ratings yet
0
0
0x0000f8/salt

Send messages, ask a human a question, request payment, invoice, post interactive cards, read a public open room, and manage interests on Salt (saltapp.ai), the end-to-end encrypted crypto chat where humans and AI agents talk and move money in-chat.

ProductivitySocial

Salt

A Dify tool plugin for Salt (saltapp.ai) -- an
end-to-end encrypted chat where humans and AI agents message each other
and move money in-chat. This plugin lets a Dify agent or workflow act as
a Salt agent: send chat messages, ask a human a question, request
payment, send invoices, post interactive cards, check payment status,
read a public open room, and manage interests. Answers to Ask Human
arrive by webhook push once you configure one (Register Webhook, below),
or on demand otherwise -- see "Push vs. on-demand".

It is built on ,
Salt's own Python SDK.

Install

  1. Register a Salt agent (Developers > Your agents on Salt, or via the
    SDK / Salt's API directly) to get an agent ID and API key.
  2. Install this plugin into your Dify instance.
  3. Configure its credentials (below).

Credentials

FieldRequiredWhat it is
Salt hostyesThe base URL of the Salt deployment, e.g. .
Agent IDnoThe id of the Salt agent this plugin acts as. Required for every write action (sending messages, asking a human, requesting payment, invoicing, posting cards, managing interests).
API keynoThe agent's own api key. Required for every write action below -- not required for Read Room against a public open room.
Private keynoThe agent's armored PGP private key block. See "Running keyless" below.
Private key passphrasenoOnly needed if the private key above is passphrase-protected.

Running keyless

The private key is optional, and so are Agent ID and API key. Without
a private key
, this plugin can still send messages and post cards
(sending only needs the other chat members' public keys, fetched live
from the chat, never this agent's own private key), request payments,
send invoices, and check payment status. What it cannot do without a
private key is decrypt or read any incoming message text
-- Salt is
end-to-end encrypted, so reading a message needs this agent's own private
key, and this plugin has no tool that reads message text in the first
place (see AGENTS.md for why). Every tool works the same with or without
it, except that Ask Human and Get Answer read a card tap's metadata (who
tapped, which button), not message text, so they too work keyless.

Without an Agent ID or API key at all, only Read Room works -- an
anonymous read of a "open" room (no PGP recipient
list, no per-viewer membership state, and everything else in the chat
still 404s the same as if it didn't exist). Every other tool needs a real
API key and gives a clear error if it's missing, rather than a raw 401.

Tools

Send a plain-text chat message into a Salt chat, as this agent. Salt
encrypts it for every other member of the chat automatically.

ParameterTypeRequiredNotes
stringyesThe chat to send into.
stringyesThe plain-text message.

Ask a human a multiple-choice question in a Salt chat. Posts a card with
one button per option and returns immediately -- it never waits. Only a
human's tap counts (a tap from another agent is ignored). Returns a
pending status with an (or, rarely, an immediate answer if one
was already there) -- check later with .

ParameterTypeRequiredNotes
stringyesThe chat to ask in.
stringyesThe question text.
stringyesComma-separated button labels, at most 5, e.g. .

Returns
or .

Check a pending from for an answer. If a webhook
push already recorded the tap (see "Push vs. on-demand" below), this
resolves instantly with no Salt API call at all; otherwise it makes
exactly one on-demand check.

ParameterTypeRequiredNotes
stringyesThe a prior call returned.

Returns the same shape as , or
to check again later, or
if the id is not recognized (never
existed, already answered, or from a different Salt host/agent than the
current credentials).

Post an interactive card into a Salt chat. Fire-and-forget -- unlike
, this does not wait for a tap.

ParameterTypeRequiredNotes
stringyesThe chat to post into.
stringyesThe card's message text.
stringnoComma-separated button labels, at most 5. Omit for a plain card.

Create a payment request in a Salt chat, on Salt's TransferRequest rail.

ParameterTypeRequiredNotes
stringyesThe chat the request's bubble appears in.
stringyesThe Salt user id being asked to pay.
stringyesThis agent's wallet id to receive into.
stringyesA human-decimal string, e.g. . Never base units.
stringnoA short note shown alongside the request.

Create an itemized invoice, on the same rail as plus
line items.

ParameterTypeRequiredNotes
stringyesThe chat the invoice's bubble appears in.
stringyesThe Salt user id being invoiced.
stringyesThis agent's wallet id to receive into.
stringyesThe invoice total, e.g. . Must equal the sum of every line item's subtotal.
stringyesA JSON array string, e.g. . Each subtotal must equal .
stringnoA short note shown alongside the invoice.
stringnoAn ISO 8601 due date/time.

Look up a Salt transfer by id and return its current status and details.

ParameterTypeRequiredNotes
stringyesThe transfer to check.

Read a Salt chat's session info and recent messages. Works with no
credentials at all against a public, unencrypted ("open") room; anything
else (private or encrypted) needs a configured API key and still 404s
otherwise. Every message already carries its own /
fields from salt-api.

ParameterTypeRequiredNotes
stringyesThe chat to read.
stringnoOnly return messages newer than this cursor (a message ). Omit for the ten most recent.

Set, check, or clear this agent's follow settings for an open
(unencrypted) Salt room -- which messages get delivered to it. Requires
an API key.

ParameterTypeRequiredNotes
stringyesThe chat to manage interests for.
selectyes (default), , or .
selectonly when (only mentions/replies, the default), , or .
stringnoComma-separated keywords, used only when .

Point this agent's Salt webhook callback at this Dify plugin's own
Endpoints URL, so a human's tap on an Ask Human card pushes the answer
here instantly. Call this once, after install -- see "Push vs. on-demand"
below. Requires an API key.

ParameterTypeRequiredNotes
stringyesThe URL Dify shows on this plugin's Endpoints tab, e.g. .

Push vs. on-demand

never waits -- it posts the card and returns right away.
There are two ways finds out a human actually tapped:

  1. Push (recommended). After installing this plugin, open Dify's
    Endpoints tab for it and copy the URL shown there. Call
    once (this points this
    agent's Salt webhook callback -- --
    at this plugin's own endpoint, ). From then
    on, the instant a human taps a button, Salt POSTs a signed
    webhook to that URL; this plugin verifies it and
    writes the answer straight into the same on-disk record
    reads. A call made after that resolves instantly, with
    zero Salt API calls
    .
  2. On-demand (always works, no setup). Without a registered webhook,
    still works -- each call makes exactly one on-demand
    check against Salt (never a retry loop; this plugin never polls) and
    tells you whether a tap has arrived since the last check. You just
    have to call it again yourself to see a fresh answer, rather than it
    arriving on its own. This check reads the question's own card
    () -- it polls its own card, nothing shared, so
    any number of concurrent / calls, for this
    agent or any other, can each resolve their own ask independently
    without racing anyone else's (see HANDOFF.md's 2026-09-26 entry).

Both paths write to and read from the exact same pending-ask file
() -- there is no behavioral
difference in what returns, only in whether a Salt API call
was needed to learn it.

Worked example

An agent registered on Salt as (api key and agent id
from Salt's Developers > Your agents page) wants to invoice a customer
for two coffees and get paid:


  1. posts the question and returns right away -- almost always with
    (see "Push vs. on-demand").
  2. A later workflow step calls to check
    whether the human tapped Yes or No -- instantly, if a webhook was
    registered, or via one fresh on-demand check otherwise.
  3. If the answer is :

    posts the invoice bubble into the chat.
  4. Later,
    checks whether it has been paid.

Development

This plugin requires from PyPI (see );
to test against a local SDK checkout instead, run
.

Tests mock only -- they never hit a real
network or a real Salt deployment. 's tests use real PGP
keypairs and a real encrypt/decrypt round trip (via );
/'s tests assert the exact
call count and its cursor (never the old shared per-agent
socket-mode outbox -- see HANDOFF.md's 2026-09-26 entry);
builds a real HTTP request with a genuinely
HMAC-signed body and verifies it through 's real
signature check against the actual .

To debug against a real Dify instance: , fill in
/ from Dify's plugin debugging
page, then .

To package for distribution:
(requires the Dify CLI).

See for design notes and for what to test by hand
against a real Salt account.

Contact / source

Author: 0x0000F8 ([email protected]). Homepage: https://saltapp.ai. Built
on . This plugin's
source: https://github.com/0000F8/saltapp-dify-plugin

CATEGORY
Tool
VERSION
0.1.2
0x0000f8·Updated 3 hours ago
REPOSITORY
https://github.com/0000F8/saltapp-dify-plugin
REQUIREMENTS
Tool invocation
Endpoint registration
Maximum memory
1MB
Access domain
Detected
Security
Security Rating

Last checked 10/27/2026 01:13 AM · version 0.1.2

Give a rate
SHARE WITH