Docs/Build guides/Add from wallet

Add from wallet

Prepare and store a signed redemption that burns tokenized loyalty value so the brand can credit or restore offchain points/value.

GoalAdd tokenized loyalty value back into the brand account.

Create a redemption when a logged-in customer proves wallet ownership and burns tokenized loyalty value so the brand can credit or restore offchain points/value. A brand can also map this to a discount, product, upgrade, or access pass, but the default integration model is an offramp back to the brand's ledger.

Inputs#

FieldTypeRequiredMeaning
issueraddressyesBrand wallet that signs the redemption.
fromaddresssessionCustomer wallet whose tokenized balance is burned. Not part of the issuer-signed terms; add it with the holder signature or collect it on checkout.
loyaltyIdbytes32yesBrand-scoped program ID.
amountuint256 stringyesTokenized loyalty amount to burn and reconcile offchain. Must be greater than zero.
expiresAtuint256 stringyesThe exact bucket to burn. Use 0 for non-expiring balances.
deadlineuint256 stringyesLast Unix timestamp when the redemption can be submitted. Use 0 for no execution deadline.
noncebytes32yesUnique per issuer. Replays are rejected.
chainIduint256 stringyesExpected chain ID. Loyfin uses Base 8453.
verifyingContractaddressyesThe Loyfin factory that will execute the action.
operationHashbytes32optionalBrand reference hash for correlating this action with an internal database row. Defaults to zero bytes when omitted.
datahex bytesoptionalBrand-defined fulfillment data. Defaults to 0x. Max 2048 bytes.

Request#

Redemption bodyjson
{
  "redemption": {
    "issuer": "0x1111111111111111111111111111111111111111",
    "loyaltyId": "0x4242424242424242424242424242424242424242424242424242424242424242",
    "amount": "250",
    "expiresAt": "0",
    "deadline": "0",
    "nonce": "0x7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a",
    "chainId": "8453",
    "verifyingContract": "0x3333333333333333333333333333333333333333",
    "operationHash": "0x9999999999999999999999999999999999999999999999999999999999999999",
    "data": "0x"
  },
  "signature": "0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab"
}
TypeScript SDK — Upcoming releasetypescript
import { Loyfin, redemptionTypedData } from "@loyfin/server";

const loyfin = new Loyfin({ apiKey: process.env.LOYFIN_API_KEY });

const typedData = redemptionTypedData(redemption);
const signature = await issuerSigner.signTypedData(typedData);

const { redemption: session, duplicate } = await loyfin.redemptions.create({
  redemption,
  signature
});

// Show session.checkoutUrl when the holder still needs to sign.

Fulfillment#

Loyfin burns the signed tokenized amount from the customer's selected bucket. The issuer only needs to publish the signed redemption; Loyfin's official relayer or an independent relayer can submit it. Your brand system should credit, restore, or fulfill the offchain result only after the redemption is completed.

Common errors#

  • Customer has insufficient balance in the selected expiry bucket.
  • The bucket is expired.
  • The action deadline has passed.
  • The signature, nonce, chain, or verifying contract does not match.

Brand database flow#

Treat redemption as a pending brand operation until it is confirmed.

Add from wallet usually starts inside the brand app: the customer is logged in, connects a wallet, proves ownership with a brand-scoped wallet signature, chooses tokenized value to add back, and the app calls your brand API. Your backend verifies the wallet/account mapping, creates an internal redemption row, signs the redemption, and stores it through Loyfin or submits it onchain directly. The brand database remains the system of record for customer balance, support, and account state.

  • Use operationHash to connect the signed redemption, indexed Loyfin activity, and your internal redemption row.
  • A pasted address is not enough for Add from wallet. The customer should prove wallet ownership before the brand credits an offchain account.
  • After POST /redemptions returns successfully, keep the brand operation pending until the burn is confirmed.
  • On confirmation, apply the brand-side result: credit or restore the offchain points/value, update the account record, and show the customer the completed add-from-wallet receipt.
  • The helper API is the default path for performance and efficiency. Confirmation can come from account-level webhooks, polling GET /operations or GET /redemptions, or direct onchain event reads. Brands can also submit the redeem transaction themselves instead of relying on the helper API.

Receipt processing#

Credit offchain value exactly once for each completed burn.

Loyfin indexes completed burns in redemptions. For a wallet-linked account, a brand can query completed rows by wallet and token address, then process only receipts that are not already marked completed in the brand database.

Find completed burns for one wallet and tokenbash
curl "https://api.loyfin.com/redemptions?from=0x2222222222222222222222222222222222222222&token=0x4444444444444444444444444444444444444444&chainId=8453&limit=100"
  • Store a processed key such as chainId + txHash + logIndex, plus operationHash when available.
  • Verify the receipt belongs to the brand's expected issuer/token before adding offchain value.
  • Sum only unprocessed rows for the wallet mapped to the logged-in brand account, then mark them processed in the same brand-side transaction that credits the points.

State machine#

Offchain credit should wait for the tokenized value to be burned.

01

Requested

The logged-in customer starts Add from wallet in the brand app.

02

Authorized

Your backend verifies wallet ownership, customer identity, token bucket, and internal account constraints.

03

Created

POST the signed redemption to Loyfin and keep the offchain credit pending in your own system.

04

Credited

After the redemption is mined, add the offchain points/value and store the receipt key for support.

Loyfin is built onBase