{ "openapi": "3.0.0", "info": { "title": "Payment Service", "version": "0.1.0" }, "servers": [ { "url": "/v1" } ], "components": { "schemas": { "ByteCount": { "type": "integer", "description": "A positive integer representing a byte count of data items", "pattern": "^[0-9]+$", "example": 5242880 }, "CreditResponse": { "type": "object", "properties": { "winc": { "$ref": "#/components/schemas/Winc" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "BalanceResponse": { "properties": { "controlledWinc": { "type": "string", "description": "The total amount of winc that a user has if they revoked all approvals they've created" }, "winc": { "type": "string", "description": "The total amount of winc the user can spend without using any approved balances given to them" }, "effectiveBalance": { "type": "string", "description": "The total amount of winc that can currently be spent by the user's balance, including any shared Credits" }, "givenApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" }, "receivedApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" } } }, "PaymentCreditResponse": { "type": "object", "properties": { "winc": { "$ref": "#/components/schemas/Winc" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" }, "fees": { "$ref": "#/components/schemas/Adjustment" }, "actualPaymentAmount": { "$ref": "#/components/schemas/ActualPaymentAmount" }, "quotedPaymentAmount": { "$ref": "#/components/schemas/QuotedPaymentAmount" } } }, "ActualPaymentAmount": { "type": "integer", "description": "The actual payment amount a user will spend in the given currency's smallest unit value. For example, $8 USD is 800", "example": 800 }, "QuotedPaymentAmount": { "type": "integer", "description": "The quoted payment amount without adjustments in the given currency's smallest unit value. For example, $10 USD is 1000", "example": 1000 }, "Winc": { "type": "string", "description": "A big number string representing an amount of credits in winc. One credit is equivalent to 10^12 winc", "example": "332824926" }, "Adjustment": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "operatorMagnitude": { "type": "number" }, "operator": { "type": "string" }, "adjustmentAmount": { "type": "string" }, "promoCode": { "type": "string" } } }, "example": [ { "name": "Adjustment", "description": "Some great subsidy", "operatorMagnitude": "0.6", "operator": "multiply", "adjustmentAmount": "-12300", "promoCode": "SOME-GREAT-CODE" } ] }, "CurrencyType": { "type": "string", "description": "Currency type for a given payment amount", "example": "usd" }, "TokenType": { "type": "string", "description": "Token type for a given transaction", "example": "arweave" }, "PriceFiatOrTokenType": { "type": "string", "description": "Type for a given price request. Either \"fiat\" type or \"token\" type", "example": "kyve" }, "PaymentAmount": { "type": "integer", "description": "Payment amount in a given currency's smallest unit value. For example, $10 USD is 1000. 1 AR is 1000000000000", "example": 1000 }, "SignatureHeader": { "type": "string", "description": "The signature value derived from signing the request's data concatenated with the provided nonce using the private key from the provided public key" }, "NonceHeader": { "type": "string", "description": "The nonce value concatenated with the request's data when deriving the provided the signature" }, "PublicKeyHeader": { "type": "string", "description": "The \"modulus\" of the JWK used to create the signature header" }, "PromoCode": { "type": "string", "description": "Comma-separated list of promo codes" }, "DestinationAddress": { "type": "string", "description": "Destination wallet address for payment", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "DestinationAddressType": { "type": "string", "description": "Destination wallet address type", "example": "arweave" }, "WinstonCreditAmount": { "type": "string", "description": "A big number string representing an amount of credits in winc. One credit is equivalent to 10^12 winc", "example": "332824926" }, "PendingPaymentTx": { "type": "object", "description": "A payment transaction as our service sees it", "properties": { "transactionId": { "type": "string", "description": "The transaction ID of the pending payment transaction" }, "transactionQuantity": { "type": "integer", "description": "The quantity of the pending payment transaction" }, "createdAt": { "type": "string", "description": "The date and time the transaction was entered into the service" }, "tokenType": { "$ref": "#/components/schemas/TokenType" }, "destinationAddress": { "$ref": "#/components/schemas/DestinationAddress" }, "destinationAddressType": { "$ref": "#/components/schemas/DestinationAddressType" }, "winstonCreditAmount": { "$ref": "#/components/schemas/WinstonCreditAmount" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "CreditedPaymentTx": { "type": "object", "description": "A payment transaction as our service sees it", "properties": { "allOf": { "$ref": "#/components/schemas/PendingPaymentTx" }, "blockHeight": { "type": "integer", "description": "The block height at which the transaction was credited" }, "creditedAt": { "type": "string", "description": "The date and time the transaction was credited in the service" } } }, "FailedPaymentTx": { "type": "object", "description": "A payment transaction as our service sees it", "properties": { "allOf": { "$ref": "#/components/schemas/PendingPaymentTx" }, "failedAt": { "type": "string", "description": "The date and time the transaction failed in the service" }, "failureReason": { "type": "string", "description": "The reason the transaction failed in the service" } } }, "TopUpQuote": { "type": "object", "description": "A copy of the top up quote that was saved to the service's database", "properties": { "topUpQuoteId": { "type": "string", "example": "caa8b54a-eb5e-4134-8ae2-a3946a428ec7" }, "destinationAddress": { "$ref": "#/components/schemas/DestinationAddress" }, "destinationAddressType": { "$ref": "#/components/schemas/DestinationAddressType" }, "paymentAmount": { "$ref": "#/components/schemas/ActualPaymentAmount" }, "quotedPaymentAmount": { "$ref": "#/components/schemas/QuotedPaymentAmount" }, "currencyType": { "type": "string", "example": "usd" }, "winstonCreditAmount": { "$ref": "#/components/schemas/WinstonCreditAmount" }, "quoteExpirationDate": { "type": "string", "example": "2023-05-17T21:46:38.404Z" }, "paymentProvider": { "type": "string", "example": "stripe" } } }, "ConversionRates": { "type": "object", "properties": { "winc": { "type": "string", "description": "A big number representing the amount of credits in winc that 1GB of storage costs based on current market rates. One credit is equivalent to 10^12 winc.", "example": 332824926 }, "fiat": { "type": "object", "description": "The amount of fiat currencies that 1GB of storage costs based on current market rates.", "example": { "aud": 8.1228081675468, "brl": 26.0465204865588, "cad": 7.1550718332636, "eur": 4.9519274126615995, "gbp": 4.251862830414, "hkd": 42.3539072259708, "inr": 443.50120792114916, "jpy": 781.2411885860027, "sgd": 7.3197929114399995, "usd": 5.4049103776452005 } }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "PaymentSession": { "type": "object", "description": "The full payment-intent or checkout-session from a payment provider", "properties": { "id": { "type": "string", "description": "The payment provider's given ID for this payment intent", "example": "cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy" }, "client_secret": { "type": "string", "description": "Available on the payment-intent top up flow, this is the client secret that must be provided in order to confirm the payment intent with a payment method", "example": "cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy#fidkdWxOYHwnPyd1blpxYHZxWjA0T1BEcXJGPWR1VUpSbkFJbTdDVV9uVG5sTl9AblFqM3J0YklGcVRqRmlJM1YxaTdvaWdnZjBIYkphckpQYVA8UWs8NktLc3REQmdwNDQwaW5PRm1IbG5CNTVdUGNRaGo3fycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl" }, "url": { "type": "string", "description": "Available on a checkout-session top up flow, this is the URL in which to fulfill the quote", "example": "https://checkout.stripe.com/c/pay/cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy#fidkdWxOYHwnPyd1blpxYHZxWjA0T1BEcXJGPWR1VUpSbkFJbTdDVV9uVG5sTl9AblFqM3J0YklGcVRqRmlJM1YxaTdvaWdnZjBIYkphckpQYVA8UWs8NktLc3REQmdwNDQwaW5PRm1IbG5CNTVdUGNRaGo3fycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl" } } }, "ReturnUrl": { "type": "string", "description": "The URL to return to after a successful payment", "default": "https://app.ardrive.io" }, "SuccessUrl": { "type": "string", "description": "The URL to return to after a successful payment", "default": "https://app.ardrive.io" }, "CancelUrl": { "type": "string", "description": "The URL to return to after a canceled payment", "default": "https://app.ardrive.io" }, "UiMode": { "type": "string", "description": "Which UI Mode to create the checkout session in", "default": "hosted", "example": "embedded" }, "CreditShareApprovals": { "type": "array", "items": { "type": "object", "properties": { "approvalDataItemId": { "type": "string", "description": "The data item ID of the approval", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "approvedAddress": { "type": "string", "description": "Approved wallet address", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "payingAddress": { "type": "string", "description": "Paying wallet address", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "approvedWincAmount": { "type": "string", "description": "The amount of winc approved", "example": "332824926" }, "usedWincAmount": { "type": "string", "description": "The amount of winc used", "example": "332824926" }, "creationDate": { "type": "string", "description": "The date and time the approval was created", "example": "2023-05-17T21:46:38.404Z" }, "expirationDate": { "type": "string", "description": "The date and time the approval expires", "example": "2023-05-17T21:46:38.404Z" } } } } } }, "paths": { "/price/bytes/{byteCount}": { "get": { "summary": "Get Amount of Credits in winc for Byte Count", "description": "Returns the current amount of winc it will cost to upload a given byte count worth of data items", "parameters": [ { "name": "byteCount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ByteCount" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreditResponse" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid byte count" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Pricing Oracle Unavailable" } } } } } } }, "/price/{type}/{amount}": { "get": { "summary": "Get winc for Payment Type and Amount", "description": "Returns the current amount of winc this service will quote for a given payment type and amount", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "type", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/PriceFiatOrTokenType" } }, { "name": "amount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/PaymentAmount" } }, { "name": "promoCode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/PromoCode" } }, { "name": "destinationAddress", "in": "query", "required": false, "schema": { "type": "string", "description": "Destination wallet address. This will override the signature header's public key if provided" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentCreditResponse" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Payment Amount is Invalid" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Fiat Oracle Unavailable" } } } } } } }, "/balance": { "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "address", "in": "query", "required": false, "schema": { "type": "string", "description": "Destination wallet address, required if no signature headers are provided" } } ], "get": { "summary": "Get Current Balance of winc", "description": "Use a signed request or a previously obtained JWT to get the signing wallet's current service balance in winc", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BalanceResponse" } } } }, "403": { "description": "Forbidden", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid signature or missing required headers" } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "User Not Found" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Cloud Database Unavailable" } } } } } } }, "/top-up/{method}/{address}/{currency}/{amount}": { "get": { "summary": "Get Top Up Quote for Credits", "description": "Get a top up quote and payment session for a given method (payment-intent or checkout-session), destination address, currency type, and payment amount", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "method", "in": "path", "required": true, "schema": { "type": "string", "example": "checkout-session" } }, { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "Destination wallet address" } }, { "name": "currency", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/CurrencyType" } }, { "name": "amount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/PaymentAmount" } }, { "name": "promoCode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/PromoCode" } }, { "name": "uiMode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/UiMode" } }, { "name": "returnUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ReturnUrl" } }, { "name": "successUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/SuccessUrl" } }, { "name": "cancelUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/CancelUrl" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "paymentSession": { "allOf": [ { "$ref": "#/components/schemas/PaymentSession" } ] }, "topUpQuote": { "allOf": [ { "$ref": "#/components/schemas/TopUpQuote" } ] }, "adjustments": { "$ref": "#/components/schemas/Adjustment" }, "fees": { "$ref": "#/components/schemas/Adjustment" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Payment Amount is Invalid!" } } } }, "403": { "description": "Forbidden", "content": { "text/plain": { "schema": { "type": "string", "default": "Destination address is not a valid Arweave native address!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Fiat Oracle Unavailable" } } } } } } }, "/currencies": { "get": { "summary": "Get Supported Currencies", "description": "Returns the current list of currency types supported by this service", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "supportedCurrencies": { "type": "array", "example": [ "usd", "jpy" ], "items": { "type": "string" } }, "limits": { "type": "object", "example": { "usd": { "minimumPaymentAmount": 500, "maximumPaymentAmount": 1000000, "suggestedPaymentAmounts": [ 2500, 5000, 10000 ], "zeroDecimalCurrency": false }, "jpy": { "minimumPaymentAmount": 750, "maximumPaymentAmount": 1500000, "suggestedPaymentAmounts": [ 3500, 6500, 15000 ], "zeroDecimalCurrency": true } } } } } } } } } } }, "/countries": { "get": { "summary": "Get Supported Countries", "description": "Returns the current list of currency types supported by this service", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "array", "example": [ "United Kingdom", "United States" ], "items": { "type": "string" } } } } } } } }, "/rates": { "get": { "summary": "Get conversion rates for 1GB of storage", "description": "Returns the supported fiat currency conversion rates for 1GB of storage based on current market prices.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversionRates" } } } } } } }, "/rates/{currency}": { "get": { "summary": "Get current conversion rate for 1 AR for a given currency", "description": "Returns the supported fiat currency conversion rate for 1AR based on current market prices.", "parameters": [ { "name": "currency", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/CurrencyType" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "currency": { "type": "string", "example": "usd" }, "rate": { "type": "number", "example": 5.61 } } } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid currency" } } } } } } }, "/redeem": { "get": { "summary": "Redeem credits gifted via email", "description": "Redeem credits gifted via email by providing the destination wallet address for the credits, the redemption ID, and recipient email address", "parameters": [ { "name": "destinationAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Destination wallet address" } }, { "name": "id", "in": "query", "required": true, "schema": { "type": "string", "description": "ID for the redemption" } }, { "name": "email", "in": "query", "required": true, "schema": { "type": "string", "description": "Recipient email address for the redemption" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Payment receipt redeemed for 1000 winc!" }, "userBalance": { "type": "string", "example": 1000 }, "userAddress": { "type": "string", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "userCreationDate": { "type": "string", "example": "2023-05-17T21:46:38.404Z" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Failure to redeem payment receipt!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Error while redeeming payment receipt. Unable to reach Database!" } } } } } } }, "/account/balance/{token}": { "post": { "summary": "Post a pending payment transaction", "description": "Post a transaction ID that has been sent to the payment service's wallet", "requestBody": { "required": true, "description": "JSON with `tx_id` key of the pending payment transaction", "content": { "application/json": { "schema": { "type": "object", "properties": { "tx_id": { "type": "string", "description": "The transaction ID of the pending payment transaction" } } } } } }, "parameters": [ { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Transaction credited" }, "creditedTransaction": { "$ref": "#/components/schemas/CreditedPaymentTx" } } } } } }, "202": { "description": "Accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Transaction pending" }, "pendingTransaction": { "$ref": "#/components/schemas/PendingPaymentTx" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Transaction ID is invalid!" } }, "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Transaction has already failed!" }, "failedTransaction": { "$ref": "#/components/schemas/FailedPaymentTx" } } } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "Transaction ID not found!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Error while processing transaction!" } } } } } } }, "/account/approvals": { "get": { "summary": "Get credit share approvals for a given payingAddress and approvedAddress", "description": "Get credit share approvals for a given payingAddress and approvedAddress", "parameters": [ { "name": "payingAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Paying wallet address" } }, { "name": "approvedAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Approved wallet address" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "approvals": { "$ref": "#/components/schemas/CreditShareApprovals" }, "amount": { "type": "string", "example": "332824926", "description": "Total amount of remaining approved winc for the given payingAddress and approvedAddress" }, "expiresBy": { "type": "number", "example": 123456789, "description": "The unix timestamp of the earliest expiration date on the approval" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Invalid paying address!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Internal server error" } } } } } } }, "/account/approvals/get": { "get": { "summary": "Get all credit share approvals for a given payingAddress and approvedAddress", "description": "Get all credit share approvals for a given userAddress", "parameters": [ { "name": "userAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Paying wallet address" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "givenApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" }, "receivedApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Invalid paying address!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Internal server error" } } } } } } }, "/info": { "get": { "summary": "Get service information", "description": "Get the current version of the service and the addresses for the supported blockchains", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "version": { "type": "string", "example": "0.2.0" }, "addresses": { "type": "object", "properties": { "arweave": { "type": "string", "example": "JNC6vBhjHY1EPwV3pEeNmrsgFMxH5d38_LHsZ7jful8" }, "ethereum": { "type": "string", "example": 6.053775100077233e+47 }, "solana": { "type": "string", "example": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i" }, "matic": { "type": "string", "example": 6.053775100077233e+47 }, "kyve": { "type": "string", "example": "kyve1clmuh5sjw73784lg0gnf4p07qefzrtk78an698" } } }, "gateway": { "type": "string", "example": "https://arweave.net/" } } } } } } } } } } }